Java reflection mechanism (IV)-additional articles, in-depth instantiation methods, and external articles of java

Source: Internet
Author: User

Java reflection mechanism (IV)-additional articles, in-depth instantiation methods, and external articles of java
Reflection mechanism these blog posts are written down and found to involve the Java class loading mechanism. This part of content is also a relatively independent part, so it is written separately. In JAVA, any class must be loaded into JVM to run. Previously, Class Loader introduced the loading mechanism of classes. Here we will talk about the comparison between different loading methods, so that we can have a deeper understanding of the JAVA Class instantiation process.
New and Class. newInstance we say that the new keyword in the code means that the coupling of code that may change is too high. In this case, we will use the reflection mechanism to remove the new Keyword, which we have seen in the proxy mode. In fact, Class. newInstance is used instead. This indicates that both methods can get the same object instance, but there is a difference between them, and the coupling degree is different.
In fact, we can think that the Class. newInstanc method to instantiate an object is to split the new Keyword into two steps. Because the usage of Class. newInstance is prerequisite, ensure that the Class has been loaded to JVM and linked. See the following code:

<Span style = "font-family: FangSong_GB2312; font-size: 18px;"> <span style = "font-family: FangSong_GB2312; "> public static void main (String [] arg) throws ClassNotFoundException, InstantiationException, IllegalAccessException {// get the currently running loader ClassLoader cl = Thread from the current Thread. currentThread (). getContextClassLoader (); cl. loadClass ("com. zjj. classTest. test "); // load the Test Class to JVM Class c2 = cl. getClass (); // obtain the Class Object c2.newInstance () of the Class; // instantiate the object }}</span> </span>
Here, Class. forName is not used to obtain the Class object to ensure that the Class is loaded but not linked. This code looks like there is nothing wrong with it, and there is no problem with compilation, but an error occurs during running. That is to say, the class loaded using the above method is not linked, so the newInstance method cannot be executed.
Previously, we can simply think that the Class. Instance method is the two steps of the new split, but in fact the new method does more than the Class. Instance method. The Class. Instance method can only access constructor without parameters, but can access all new constructor methods. Create a test class with two constructors and check the client call code:
<span style="font-family:FangSong_GB2312;font-size:18px;"><span style="font-family:FangSong_GB2312;">public static void main(String[] arg) throws ClassNotFoundException, InstantiationException, IllegalAccessException{    Class c=Class.forName("com.zjj.ClassTest.Test");       c.newInstance();             new Test("ni");        }}</span></span>
Output result:
Constructors without Parameters
Constructors with Parameters
If you input a parameter in newInstance to call a constructor with a parameter, an error is returned and compilation fails. NewInstance is weak and new is strong.
Class. forName and classLoad. loadClass: before talking about these two differences, we should first understand that JVM will execute static code segments. Remember the concept that static code is bound to class, if the class is loaded successfully, the static code is executed and the static code will not be followed. That is to say, the static code segment is executed only once when the class is loaded. In addition, we also need to know that the loading process of classes is divided into loading, connection, and initialization. In addition, when the JVM encounters a Class request, it first checks whether the memory exists. If the memory does not exist, it loads it. If the memory does not exist, it returns an existing Class object.
The difference between the two methods is that the three processes are different. ForName has two functions (polymorphism). If forName (String className, boolean initialize, ClassLoader loader) is set to True, the class is linked and initialized. If it is set to False, it will not be connected or initialized if it does not exist. If there is a connected Class object, it will be returned but will not be initialized. The default value of initialize is True for a single parameter.
When loadClass is also a single parameter of multi-state loadClass (String name), resolve = false. If the Class has been loaded by the class loader, return the instance of the loaded Class. Otherwise, use the custom class loader to load the Class, at this time, I do not know whether the connection is successful. It will never be initialized! The only guarantee is that this class is loaded. But I don't know if this class is connected and initialized.
When loadClass (String name, boolean resolve) resolve = true, it is guaranteed that it has been loaded and connected. When resolve = falses, it is only to load this class and does not care whether it is connected or not, so it may be connected or not. The following code verifies the above content through testing:
Test class:
<Span style = "font-family: FangSong_GB2312; font-size: 18px;"> <span style = "font-family: FangSong_GB2312;"> public class Test {static {System. out. println ("static initialization");} public Test () {System. out. println ("constructor without Parameters");} public Test (String str) {System. out. println ("constructor with Parameters");} {System. out. println ("non-static initialization") ;}</span> </span>
Test 1: Client call code
<span style="font-family:FangSong_GB2312;font-size:18px;"><span style="font-family:FangSong_GB2312;">public static void main(String[] arg) throws ClassNotFoundException, InstantiationException, IllegalAccessException{    Class c=Class.forName("com.zjj.ClassTest.Test");     }}</span></span>
The output result is static initialization.
Note: Class. forName performs three steps: Loading, connection, and initialization.
Test 2: Changed the client code
<span style="font-family:FangSong_GB2312;font-size:18px;"><span style="font-family:FangSong_GB2312;">public static void main(String[] arg) throws ClassNotFoundException, InstantiationException, IllegalAccessException{    ClassLoader cl=Thread.currentThread().getContextClassLoader();    Class c=Class.forName("com.zjj.ClassTest.Test", false, cl);     }}</span></span>
If the output result is initialize = true, It is output and initialized statically. No output when the value is false.
Note: If this parameter is set to true, the class performs three steps: Loading, connection, and initialization. If this parameter is set to false, no Initialization is performed.
Test 3: Changed the client code
<span style="font-family:FangSong_GB2312;font-size:18px;"><span style="font-family:FangSong_GB2312;">public static void main(String[] arg) throws ClassNotFoundException, InstantiationException, IllegalAccessException{    ClassLoader cl=Thread.currentThread().getContextClassLoader();    Class c=Class.forName("com.zjj.ClassTest.Test", false, cl);               c.newInstance();     }}</span></span>
Output result:
Static Initialization
Non-static Initialization
Constructors without Parameters
Note: To ensure that no previously loaded class exists in the JVM, the JVM memory is specially cleared. But the output result remains unchanged. If it is false, the load and link are executed. Otherwise, newInstance cannot be executed (the execution condition of newInstance was mentioned earlier ). However, the information says there may still be no connection !! To be verified.
Test 4: Changed the client code
<span style="font-family:FangSong_GB2312;font-size:18px;"><span style="font-family:FangSong_GB2312;">public static void main(String[] arg) throws ClassNotFoundException, InstantiationException, IllegalAccessException{               Class c=Class.forName("com.zjj.ClassTest.Test");    ClassLoader cl=Thread.currentThread().getContextClassLoader();    Class c=Class.forName("com.zjj.ClassTest.Test", true, cl);             }}</span></span>
The output result is static initialization.
Note: If a previously loaded class exists, the returned class exists when the second load request is executed. Because static Initialization is only executed once.
Test 5: Changed the client code
<Span style = "font-family: FangSong_GB2312; font-size: 18px;"> <span style = "font-family: FangSong_GB2312; "> public static void main (String [] arg) throws ClassNotFoundException, InstantiationException, IllegalAccessException {// get the currently running loader ClassLoader cl = Thread from the current Thread. currentThread (). getContextClassLoader (); cl. loadClass ("com. zjj. classTest. test "); // load the Test Class to JVM Class c2 = cl. loadClass ("com. zjj. classTest. test "). getClass (); // obtain the Class Object c2.newInstance () of the Class; // instantiate the object }}</span> </span>
Output result: an error is returned.
Note: Classes loaded into the memory by the loadClass method are not connected at this time and will not be initialized. Therefore, there is no static initialization output.
Test 6: I don't know why the ClassLoader in the Code has two loadClass methods.
Summary:At this point, the method comparison is over. This blog focuses on a more detailed understanding of the JVM loading process and the differences between different methods. In fact, it is only the difference in the degree of encapsulation, that is, the difference in the granularity of methods. Of course, one thing has not been verified through my own tests. It may be that my method is incorrect or there is a problem with the information. And write down this question! Goodbye to the next blog!





Java reflection mechanism instance

The AVA reflection mechanism is in the running state. For any class, all attributes and methods of this class can be known. For any object, any method of this class can be called; this kind of dynamically obtained information and the function of dynamically calling object methods is called the reflection mechanism of java language.
The Java reflection mechanism mainly provides the following functions: to judge the class to which any object belongs at runtime; to construct the object of any class at runtime; judge the member variables and methods of any class at runtime; call the methods of any object at runtime; generate a dynamic proxy.
Reference: baike.baidu.com/view/1865203.htm

Use of java reflection mechanism

Increase Program flexibility.
Such as struts. Request distribution control.
When the request comes. Struts queries the configuration file. Find the action corresponding to the request. The method has been used.
Then, the action is instantiated through reflection. And call the response method.
If reflection is not applicable, you can only write it to the code.
Therefore, one is flexible, and the other is not flexible.
In rare cases, non-reflection is not required. In most cases, reflection is used to improve program flexibility.
Therefore, most frameworks are used. Because the framework should be applicable in more cases. High requirements on flexibility.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.