Java reflection mechanism and Java reflection mechanism

Source: Internet
Author: User

Java reflection mechanism and Java reflection mechanism

The Java reflection mechanism provides the following functions:
Determine the class to which any object belongs at runtime;
Construct any class object at runtime;
Judge the member variables and methods of any class at runtime;
Call methods of any object at runtime;
Generate a dynamic proxy.

  • Advantages and disadvantages of reflection mechanism

In fact, the advantage is to increase the flexibility of the program and avoid writing the program into the code. But the disadvantage is that performance is a problem. Reflection is equivalent to a series of interpretation operations, the performance of jvm is much slower than that of java code. It is not safe. We can get the private members of the class through the reflection mechanism.

  • Details

Reflection. This word refers to "Reflection, image, reflection". In Java, it refers to classes that are completely unknown during runtime loading, exploring, and using compilation. In other words, a Java program can load a class whose name is known only at runtime, and learn its complete structure (but does not include the definition of methods ), and generate its object entity, set its fields value, or arouse its methods. The ability of the program to examine itself is called introspection ). Reflection and introspection are two frequently mentioned terms.

Reflection contains an "inverse" concept. Therefore, to interpret reflection, you must start with "positive". Generally, when you use a class, we should first know this class and then generate instantiated objects through this class, but "reverse" refers to finding classes through objects.

Packagecn. mldn. demo; classPerson {} Public class TestDemo {Public static void main (String [] args) throwsException {Person per = newPerson (); // The System is being operated. out. println (per. getClass (). getName (); // reverse }}

The above Code uses a getClass () method, and then you can get the "package" of the object. class "name, which is" inverse ", but in this" inverse "operation, a getClass () is used as the beginning of initiating all reflection operations.
The parent class of Person is the Object class, And the getClass () method used above is the method defined in the Object class.
· Get the Class Object: public final Class <?> GetClass (), all generics in reflection are defined ?, All returned values are objects.
The object returned by this getClass () method is the object of the Class, so this Class is the source of all reflection operations. However, there is still a problem that needs to be explained before it can be used. Since the Class is the source of all reflection operations, this Class must be the most important, to get the instantiated object of this class, Java defines three methods:
Method 1: Use the getClass () method of the Object class. You do not need:

Packagecn. mldn. demo; classPerson {publicclassTestDemo {publicstaticvoidmain (String [] args) throwsException {Person per = newPerson (); // Class being operated <?> Cls = per. getClass (); // obtain the Class Object System. out. println (cls. getName (); // reverse }}

Method 2: Use "class. class" to obtain and use it when learning hibernate development in the future

Packagecn. mldn. demo; classPerson {} publicclassTestDemo {publicstaticvoidmain (String [] args) throwsException {Class <?> Cls = Person. class; // obtain the Class Object System. out. println (cls. getName (); // reverse }}

Method 3: Use a static method defined inside the Class, mainly used
· Get the Class Object: public static Class <?> ForName (String className) throws ClassNotFoundException;

Packagecn. mldn. demo; classPerson {} publicclassTestDemo {publicstaticvoidmain (String [] args) throwsException {Class <?> Cls = Class. forName ("cn. mldn. demo. person "); // obtain the Class Object System. out. println (cls. getName (); // reverse }}

Now, a new question comes. What is the use of Class objects? The Object Instantiation operation has always been completed by the constructor and keyword new. However, with the Class object, another Object Instantiation method is provided:
· Instantiate objects through reflection: public T newInstance () throws InstantiationException, IllegalAccessException;
Example: instantiate an object through reflection

Packagecn. mldn. demo; classPerson {@ Override publicString toString () {return "Person Class Instance." ;}} publicclassTestDemo {publicstaticvoidmain (String [] args) throwsException {Class <?> Cls = Class. forName ("cn. mldn. demo. person "); // obtain the Class Object obj = cls. newInstance (); // instantiate the object, same as using the keyword "new" Person per = (Person) obj; // perform a downward System transformation. out. println (per );}}

Now we can find that the Object Instantiation operation has a reflection mechanism besides the keyword new, and this operation is more complex than the previous new operation, but what's the purpose?
The development mode of the program has been stressed before: to minimize coupling, the best way to reduce coupling is to use interfaces, but even if you use interfaces, you cannot escape the keyword new, in fact, new is the key culprit of coupling.
Example: Review the previous factory design model

Packagecn. mldn. demo; interfaceFruit {publicvoideat ();} classApple implementsFruit {publicvoideat () {System. out. println ("eat apple. ") ;};} ClassFactory {public static Fruit getInstance (String className) {if (" apple ". equals (className) {return new Apple () ;}returnnull ;}} publicclassFactoryDemo {publicstaticvoidmain (String [] args) {Fruit f = Factory. getInstance ("apple"); f. eat ();}}

The above is the simplest factory design pattern previously written, but there is one of the biggest problems in this factory design pattern: If the subclass of the interface is added, the factory category must be modified, this is the biggest problem it faces, and the key cause of this biggest problem is "new". If we don't use the keyword "new" now, will it become a reflection mechanism?
The reflection mechanism only needs to "package. Class" to instantiate the object, so we can modify the factory design mode based on this operation.

Packagecn. mldn. demo; interfaceFruit {publicvoideat ();} classApple implementsFruit {publicvoideat () {System. out. println ("eat apple. ") ;};} ClassOrange implementsFruit {publicvoideat () {System. out. println (" eat oranges. ") ;};} ClassFactory {publicstaticFruit getInstance (String className) {Fruit f = null; try {f = (Fruit) Class. forName (className ). newInstance ();} catch (Exception e) {e. printStackTrace ();} returnf;} publicclassFactoryDemo {publicstaticvoidmain (String [] args) {Fruit f = Factory. getInstance ("cn. mldn. demo. orange "); f. eat ();}}

It is found that even if the subclass of the interface is added at this time, the factory class can still complete the Object Instantiation operation. This is the real factory class and all changes can be taken. From the perspective of development alone, it has little to do with developers, but for some framework technologies that will be learned in the future, this is the lifeblood of its implementation. In future program development, if a complete package is required during the operation. class "names are mostly reflected.
3.12.2 in-depth reflection Application
The above only uses the Class as the basic application for reflecting instantiated objects. But for an instantiated object, it needs to call the constructor, common method, and attribute in the Class, these operations can be completed through the reflection mechanism.
3.12.2. 1. Call Construction
The reflection mechanism can also be used to obtain the constructor in the Class. This method has been clearly defined in the Class:
The following two methods
Obtain the full structure of a class:
Public Constructor <?> [] GetConstructors () throws SecurityException
Obtain the specified parameter structure of a class:
Public Constructor <T> getConstructor (Class <?>... ParameterTypes) throws NoSuchMethodException, SecurityException

Now we can see that the above two methods return the objects of the java. lang. reflect. Constructor class.
Example: obtain all the structures in a class

Packagecn. mldn. demo; importjava. lang. reflect. constructor; classPerson {// CTRL + K publicPerson () {} publicPerson (String name, intage) {}} publicclassTestDemo {publicstaticvoidmain (String [] args) throwsException {Class <?> Cls = Class. forName ("cn. mldn. demo. Person"); // obtain the Class object Constructor <?> Cons [] = cls. getConstructors (); // get all Constructor (intx = 0; x <cons. length; x ++) {System. out. println (cons [x]) ;}}

Verification: A simple Java class mentioned earlier must have a no-argument constructor.
Example: Observe the absence of parameter construction

Packagecn. mldn. demo; classPerson {// CTRL + K privateString name; privateintage; publicPerson (String name, intage) {this. name = name; this. age = age ;}@ Override publicString toString () {return "Person [name =" + name + ", age =" + age + "]" ;}} publicclassTestDemo {publicstaticvoidmain (String [] args) throwsException {Class <?> Cls = Class. forName ("cn. mldn. demo. person "); // obtain the Class Object obj = cls. newInstance (); // instantiate the object System. out. println (obj );}}

At this time, when the program is running, the error message "java. lang. instantiationException ", because the above method requires the non-argument constructor in the class to be provided when the reflection instantiate object is used, but now there is no non-argument constructor, then we must find a construction method clearly, and then use the new method in the Constructor class to instantiate the object:
· Instantiated Object: public T newInstance (Object... initargs) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException

Packagecn. mldn. demo; importjava. lang. reflect. constructor; classPerson {// CTRL + K privateString name; privateintage; publicPerson (String name, intage) {this. name = name; this. age = age ;}@ Override publicString toString () {return "Person [name =" + name + ", age =" + age + "]" ;}} publicclassTestDemo {publicstaticvoidmain (String [] args) throwsException {Class <?> Cls = Class. forName ("cn. mldn. demo. Person"); // obtain the Class Object // obtain the Constructor of the specified parameter type <?> Cons = cls. getConstructor (String. class, int. class); Object obj = cons. newInstance ("Zhang San", 20); // The System parameter passed for the constructor. out. println (obj );}}

Obviously, it is easier and more convenient to call a method without parameters to instantiate an object than to call a method with parameters. Therefore, in all future development, where a simple Java class appears, you must provide a parameter-free structure.

3.12.2. 2. Call a common method
After a Class instantiation object is obtained, the methods in the Class must be called. Therefore, you can continue to use the Class to obtain the method definition defined in the Class:
· Get all methods: public Method [] getMethods () throws SecurityException;
· Obtain the specified Method: public Method getMethod (String name, Class <?>... ParameterTypes) throws NoSuchMethodException, SecurityException
It is found that the above methods return all the objects of the java. lang. reflect. Method class.
Example: obtain all the methods defined in a class

Packagecn. mldn. demo; importjava. lang. reflect. method; classPerson {privateString name; publicvoidsetName (String name) {this. name = name;} publicString getName () {returnname;} publicclassTestDemo {publicstaticvoidmain (String [] args) throwsException {Class <?> Cls = Class. forName ("cn. mldn. demo. person "); // obtain the Class Object Method met [] = cls. getMethods (); // obtain all methods for (intx = 0; x <met. length; x ++) {System. out. println (met [x]) ;}}

Java.jpg


However, Method-class objects do not play the greatest role in listing methods (Method listing is used in development tools ), however, after obtaining the Method class object, you can use reflection to call the Method in the class:
· Call method: public Object invoke (Object obj, Object... args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException
Previously, "Object. Method" was used to call methods in the class, but now with reflection, you can directly use the Object class to call the operation methods of the specified subclass. (Also explain why the naming requirements for setter and getter methods are so strict ).
Example: Call the setName () and getName () methods in the Person Class Using Reflection.

Packagecn. mldn. demo; importjava. lang. reflect. method; classPerson {privateString name; publicvoidsetName (String name) {this. name = name;} publicString getName () {returnname;} publicclassTestDemo {publicstaticvoidmain (String [] args) throwsException {Class <?> Cls = Class. forName ("cn. mldn. demo. person "); // obtain the Class Object obj = cls. newInstance (); // instantiate the object. The String attribute = "name" is not transformed to Person; // The property Method setMet = cls in the class to be called. getMethod ("set" + initcap (attribute), String. class); // setName () Method getMet = cls. getMethod ("get" + initcap (attribute); // getName () setMet. invoke (obj, "Zhang San"); // equivalent to: Person object. setName ("Zhang San") System. out. println (getMet. invoke (obj); // equivalent to: Person object. getName ()} publicstaticString initcap (String str) {returnstr. substring (0, 1 ). toUpperCase (). concat (str. substring (1 ));}}

In the future development of all framework technologies, simple Java classes are so applied that they must follow the standards.
3.12.2. 3. Call a member
The last component of the class is the member (Field, also called attribute). If you want to obtain the member of the class through reflection, you can use the following method:
· Retrieve all members of this class: public Field [] getDeclaredFields () throws SecurityException;
· Get the specified Member: public Field getDeclaredField (String name) throws NoSuchFieldException, SecurityException;
The Return Value Type of these two methods is the object of the java. lang. reflect. Field Class. Next we will first observe how to obtain all the attributes of a class.
Example: obtain all attributes in a class

Packagecn. mldn. demo; importjava. lang. reflect. Field; classPerson {privateString name;} publicclassTestDemo {publicstaticvoidmain (String [] args) throwsException {Class <?> Cls = Class. forName ("cn. mldn. demo. person "); // obtain the Class Object Field [] = cls. getDeclaredFields (); // get all attributes for (intx = 0; x <field. length; x ++) {System. out. println (field [x]) ;}}

However, finding the Field actually finds an interesting operation. Two methods are provided in the Field class:
· Set the property content (similar to: Object. Property = content): public void set (Object obj, Object value)
Throws IllegalArgumentException, IllegalAccessException;
· Get attribute content (similar to: Object. Attribute): public Object get (Object obj)
Throws IllegalArgumentException, IllegalAccessException
However, in terms of class development requirements, it has always been emphasized that the attributes in the class must be encapsulated. Therefore, we need to solve the encapsulation before calling.
· Unencapsulate: public void setAccessible (boolean flag) throws SecurityException;
Example: using attributes in the reflection operation class

Packagecn. mldn. demo; importjava. lang. reflect. Field; classPerson {privateString name;} publicclassTestDemo {public static void main (String [] args) throwsException {Class <?> Cls = Class. forName ("cn. mldn. demo. person "); // obtain the Class Object obj = cls. newInstance (); // The Field nameField = cls. getDeclaredField ("name"); // locate the nameField attribute of name. setAccessible (true); // unencapsulate nameField. set (obj, "Zhang San"); // Person object. name = "Zhang San" System. out. println (nameField. get (obj); // Person object. name }}

Notes for learning Java !!! If you have any questions or want to obtain learning resources during the learning process, join the Java learning exchange group. Group Number:533586908Let's learn Java together!

Related Article

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.