Deep understanding of class objects and reflection mechanism in Java Foundation

There are three main ways to obtain class objects: @ h_ 502_ 4 @ get the class. Forname method through the instance getclass() method get the class literal constant through the instance getclass() method get @ h_502_4 @ test T1 = class clazz = system. Out. Println ("clazz:" + clazz. Getname()); GetClass () inherits from the top-level class object. It will return a class object reference representing the actual type of the object@ H_ 502_ 4@ Class. Get @ h with the forname method_ 502_ 4 @ forname method is a static member method of class class. Remember that all class objects come from this class, so the methods defined in class class are applicable to all class objects. Here, through the forname method, we can obtain the corresponding class object reference of the test class. Note that when you call the forname method, you need to catch an exception named classnotfoundexception, Because the forname method cannot detect the string passed to it in the compiler (whether there is a. Class file) the existence of the corresponding class, and it can only be checked when the program is running. If it does not exist, a classnotfoundexception exception will be thrown. @ h_502_4 @ using forname will trigger class initialization, compared with using class literal constants to obtain @ h_502_4 @ class literal constants to obtain @ h_502_4 @ class clazz = test.; this is not only simpler, but also more convenient It is safer because it is checked at compile time (so it does not need to be placed in the try statement block), and it is more effective because it eliminates the call to the forname () method. Note that when you create a reference to a class object using "." class ", the class object will not be initialized automatically. Note that when you use "." class "to create a reference to the classes object, the class object will not be initialized automatically. Preparation for using this class actually includes three steps: @ h_ 502_ 4 @ load, which is performed by the class loader, This step looks for the bytecode (usually find in the path specified by classpath, but this is not required) and create a class object from these bytecodes. Link. In the link phase, the bytecode in the class will be verified, the storage space will be distributed for the static domain, and all references created by this class to other classes will be resolved if necessary. Initialize. If the class has a superclass, the Its initialization, execute static initializer and static initialization block. staticFinal = 47 staticFinal2 = ClassInitialization. rand. nextInt(1000 System.out.ptintln("Initializing Initable" staticNonFinal = 147 System.out.println("Initializing Initable2" staticNonFinal = 74 System.out.println("Initializing Initable3" Random rand = Random(47 main(String[] args) Class initable = Initable. System. out. println("After creating Initable ref" Clas initable3 = Class.forName("Initable3" System.out.println("After creating Initable3 ref" If a static final value is a compiler constant, like initable As in staticfinal, this value can be read without initializing the initable class. However, setting a domain to static and final is not enough to ensure this behavior, for example, for initable Access to staticfinal2 will force class initialization because it is not a compile time constant@ H_ 502_ 4 @ if the static domain is not final, You always need to link (allocate storage space for the domain) and initialize before reading (initialize storage space), as shown in accessing initable2. Static non final. From the output results, it can be seen that the class object of initable class obtained through text constant does not trigger the initialization of initable class, which also verifies the previous analysis. At the same time, it is also found that it is irreversible. Staticfinal variable does not trigger initialization because staticfinal belongs to static constant at compile time , and the optimization is propagated through constants at the compilation stage. The formula stores the constant staticfinal of the initializable class in a constant pool called notinitialization class. In the future, references to the constant staticfinal of initializable class will actually be converted to references to its own constant notinitialization class pool. Therefore, after compilation, the reference to the compilation time constant will be obtained in the constant pool of notinitialization class, which is also the reference compilation time. Static constants are an important reason why initable class initialization is not triggered. However, it is not appropriate. The staticFinal2 variable is then invoked to trigger the initialization of the Initable class. Note that although staticfinal2 is modified by static and final, its value cannot be determined at compile time. Therefore, staticfinal2 is not a compilation time constant, and the initializable class must be initialized before using this variable. Initable2 and initable3 are static member variables rather than compile time constants. References trigger initialization. As for the forname method to obtain the class object, the initialization is bound to, This has been analyzed earlier@ H_ 502_ 4 @ as for the instanceof keyword, it returns a Boolean value to tell us whether the object is an instance of a specific type. As follows, use instanceof to detect whether obj is an instance object of animal type before casting. If it returns true, then conduct type conversion, so as to avoid throwing an exception of type conversion (ClassCastException) @ H_ 502_ 4@ @H_ 502_ 4 @ the isinstance method is a native method in the class class, which is also used to judge the object type. Take a simple example: @ h_ 502_ 4@ in fact, the instanceof and isinstance methods produce the same results@ H_ 502_ 4@ B print("Testing x of type " + print("x instanceof A " + (x print("x instanceof B "+ (x print("A.isinstance(x) "+ A. print("B.isinstance(x) " + B. print("x.getClass() == A.class " + (x.getClass() == A. print("x.getClass() == B.class " + (x.getClass() == B. print("x.getClass().equals(A.class)) "+ (x.getClass(). equals(A. print("x.getClass().equals(B.class)) " + (x.getClass(). equals(B. test( test (a parent class is not necessarily a certain type of a child class. The reflection mechanism is that you can know all the properties and methods of any class and call any method and property of any object in the running state. The dynamic information obtained and the function of dynamically calling methods of objects are known as the reflection mechanism of Java language. Reflection technology has always been a highlight of Java, and it is also the reflection mechanism of most frameworks (such as spring / mybatis, etc.) the backbone to be implemented. In Java, class and java reflection class libraries provide sufficient support for reflection technology. In reflection package, we usually use constructor classes to construct classes represented by class objects. By using constructor classes, we can dynamically create objects and field classes represented by class objects at runtime. By using C For the constructor class, we can dynamically modify the attribute values of member variables (including private) and method classes represented by class objects at runtime. Through this method, we can dynamically call the methods of objects (including private classes). These important classes will be explained separately below. @ h_502_4 @ constructor class exists in the reflection package (Java. Lang. reflect), It reflects the construction method of the class represented by the class object. The constructor object is obtained through the methods in class. The main methods related to class and constructor are as follows: @ h_ 502_ 4@ @H_ 502_ 4 @ let's take a simple example to understand the use of constructor object: @ h_ 502_ 4@ ConstructionTest main(String[] args) Class clazz = clazz = Class. forName("com.example.javabase.User" User user = user.setAge(20 user.setName("Jack" System.out.println("--------------------------------------------" Constructor cs1 =clazz.getConstructor(String. User user1= (User) cs1. newInstance("hiway" user1.setAge(22 System.out.println("user1:"+ System.out.println("--------------------------------------------" Constructor cs2=clazz.getDeclaredConstructor(.,String. cs2.setAccessible( User user2= (User) cs2. Newinstance (25), "hiway2" system. Out. Println ("user2:" + system. Out. Println ("----------------------------------------" constructor cons [] = (I = 0; I < cons. Length; I + + class clazzs [] = system. Out. Println ("constructor [" + I + "]" + system. Out. Print ("parameter type [" + I + "]") ("(J = 0; J < clazzs. Length; j + + (J = = clazzs. Length - 1 system. Out. Print (clazzs[j].getName() + "," System. out. println(")" . Name = user (. Age =. Name = setage (. Age =. Name = "user {" + "age =" + age + ", name = '" + name +' \ '' + '}' some common methods about the constructor class itself are as follows (only some, others can be found in the API) @ h_ 502_ 4 @ field provides information about a single field of a class or interface and dynamic access to it. The reflected field may be a class (static) field or an instance field. Similarly, we can obtain the field object representing the field information through the methods provided by class. The methods related to class and field object are as follows: @ h_502_4 @ @ h_502_4 @ the following code shows the use process of the above methods @ h_502_4 @ main (string [] args) class clazz = class forName("reflect.Student" Field field = clazz.getField("age" System.out.println("field:"+ Field fields[] = System.out.println("f:"+ System.out.println("================getDeclaredFields====================" Field fields2[] = System.out.println("f2:"+ Field field2 = clazz.getDeclaredField("desc" System.out.println("field2:" +Student} should note that if we don't want to get the fields of its parent class, we need to use getdeclared. Class/ Getdeclaraedfields method to get the fields. If we need to get the fields of the parent class jointly, we can use the get. Method of class class/ getFi., However, you can only get the fields modified by public, not the private fields of the parent class. The set (object obj, object value) method is the method of the field class itself, which is used to set the value of the field, while the get (object obj) method is used to obtain the value of the field. Of course, there are other commonly used methods for the field class as follows: these methods may be more commonly used. In fact, the field class also provides methods dedicated to basic data types, such as setint () / getInt (), setboolean () / getboolean, setchar () / getchar (), and so on. Not all are listed here. You can view the API documentation as needed. It should be noted that the field field modified by the final keyword is safe and can accept any modification at run time, but its actual value will not change in the end@ H_ 502_ 4 @ method provides information about a single method on a class or interface (and how to access the method). The reflected methods may be class methods or instance methods (including abstract methods). The following are the methods related to the method object obtained by the class: @ h_502_4 @ @ h_502_4 @ also demonstrate the above methods through a case: @ h_502_4 @ main (string [] args) class clazz = class forName("reflect.Circle" Method method = clazz.getmethod("draw",.,String. System.out.println("method:"+ Method[] methods = System.out.println("m::"+ System.out.println("=========================================" Method method1 = clazz.getDeclaredMethod("drawCircle" System.out.println("method1::"+ Method[] methods1= System.out.println("m1::" + System. out. Println ("draw" draw (system. Out. Println ("draw" + name + ", count =" + circle system. Out. Println ("drawcircle" 100} when obtaining the method object through the getmethods method, the method of the parent class will also be obtained, as shown in the above output

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>