A tentative study of Java reflection--"when class also learns to look in the mirror"

Source: Internet
Author: User
Tags float double

The function of reflection is to say the function of reflection in a straight way 1. Provides us with the ability to analyze information in a comprehensive manner 2. Dynamic load Class I understand the meaning of "reflection" (only personal understanding) I understand the Java reflection mechanism is: to provide a complete and powerful API "reflection" of the structure of the class. For example, a reflection mechanism is like a mirror, and the class is like a person in a mirror. The Mirror (reflection mechanism) shines (reflects) the full picture of a person (information about a class, such as a method, a member variable, a constructor, etc.) Why do you look in the mirror? Because I do not look in the mirror to see the whole picture, the "mirror" is to solve the problem (to provide us with a comprehensive analysis of the ability of the class)

Well, I know it sounds blurry, so let's step it up:

Class is also an object in Java there is a sentence: All things are objects, even the basic types such as int, although not the object, but the behavior is also closely related to the object (basic packaging type and automatic boxing) so there is a possibility that completely break our conventional thinking is: Class is also object "Class" Object and "class" type okay, It is not very good to say "class is also an object", and it should be said that each class in Java has a corresponding "Class" Object (Class object), which is generated by the JVM and holds information about the corresponding class. For example, suppose our Java files involve three classes: Class A, Class B, and Class C, then compile will correspond to the "Class" Object of Class A, "Class" Object of Class A, "Class" Object of Class A, which is used to save and a,b,c the corresponding information of class. Our thinking is this: An object must have a corresponding class, because only the class can instantiate the object ah, "top" of the "class object", there should be another class! The class above "class" is Java.lang.Class, which is the class of all "class" objects (which may sound awkward), so we declare a "class" object, assuming that the class object (class object) is a--
Class A
We call a "class" type, so we can actually divide the objects in Java into two types: 1. Instance Object 2. Class object So the first thing we're going to talk about today is this: the three ways to get a class object from a--class object that is different from the instance object that you normally use we assume that there is a category called MyClass:
public class MyClass {}
Then there are three ways to get the class object: First, by means of the class name.
Class classinstance= Myclass.class;

Two. The GetClass method of the instance object created by the class gets

MyClass MyClass = new MyClass (); Class classinstance = Myclass.getclass ();

Three. Obtained by means of the static method of class forname (parameter is the complete class name with package name)

Class classinstance = Class.forName ("MyPackage. MyClass ");
"Note" 1. When running forname, it is possible to throw a checked exception classnotfoundexception because the package name cannot be found, so we need to wrap it in the Try-catch statement:
try {Class classinstance = Class.forName ("MyPackage. MyClass ");} catch (ClassNotFoundException e) {//TODO auto-generated catch block E.printstacktrace ();}
2. The above three methods have the same objects, so the effect is equivalent to using the reflection API to comprehensively analyze the class information-methods, member variables, constructors as we mentioned above, a major function of reflection is to analyze the structure of a class, or to analyze all the information related to this class. And this information is the basic composition of the class: Methods, member variables, and constructors in fact, similar to the class and class objects we have described above, the methods in a class, the member variables and the constructors correspond to an object 1, respectively. Each method should have a methods object that holds information about the method, and the class to which it belongs is java.lang.reflect.method;2. Each member variable should have a Field object that holds and information about the variable, and the class to which the object belongs is Java.lang.reflect.Field3. Each constructor should have a Constructor object that holds information about the constructor and the class that this object belongs to is the Java.lang.reflect.Constructor method. Member variables and constructors are attached to a class, and for this reason, we should first obtain a class object that corresponds to one of the classes, and then consider how to get the Method/field/constructor object, which we can do through a series of methods, The corresponding method object is obtained from the class object of one of the classes, and the Field object and the constructor object assume that C is a class object: by C.getdeclaredmethods () You can obtain an array of method objects that correspond to all of the declared methods in this class by C.getdeclaredfields () to get an array of field objects that correspond to all declared member variables in this class through C.getconstructors (); You can get an array of constructor objects that correspond to all the constructors in this class, in the following example, we will iterate through the names of the methods, member variables, and constructors in a class: Myclass.java:
public class MyClass {private int value;//member Variable public MyClass (int value) {this.value = value;  }//Constructor public int GetValue () {return value;}//Method 1 public void SetValue (int value) {this.value = value; }//Method 2}
Test.java:
Import Java.lang.reflect.constructor;import Java.lang.reflect.field;import Java.lang.reflect.Method; public class Test {public static void Printclassmessage (Object obj) {Class C = Obj.getclass ();//Gets the class object for which obj belongs
Method [] methods = C.getdeclaredmethods (); Get List of Method objects
System.out.println ("traverse the name of all methods in the MyClass class:"); for (int i =0; i<methods.length; i++) {System.out.println (Methods[i].getname ()); }
Field [] fields = C.getdeclaredfields (); Gets the member Variable object list System.out.println ("traverse the name of all member variables in the MyClass class:"); for (int i =0; i<fields.length; i++) {System.out.println (Fields[i].getname ());  } Constructor [] constructors = c.getconstructors (); Gets the Constructor object list System.out.println ("traverse the name of all constructors in the MyClass class:"); for (int i =0; i<constructors.length; i++) {System.out.println (Constructors[i].getname ()); } }

public static void Main (String [] args) {MyClass MyClass = new MyClass (1);//Create a MyClass object Printclassmessage (MYCLA  SS); Print information about the class to which this object belongs}}
Operation Result:
Iterate through the names of all the methods in the MyClass class: Getvaluesetvalue iterates through the names of all the member variables in the MyClass class: value iterates through the names of all constructors in the MyClass class: Mypackage.myclass

The above example is just as a demonstration, the API of the Method/field/constructor object is certainly not limited to the simple operation of GetName to get the name, so next I will introduce the more specific reflection API

Using the reflection API to analyze method information in classes GetMethods and Getdeclaredmethods methods the difference between GetMethods and Getdeclaredmethods is: The method that the GetMethods obtains corresponds to the part that inherits from the parent class, and the method that the Getdeclaredmethods obtains does not include the part that inherits from the parent class. Public method[] GetMethods () returns all public methods of a class, including the common methods of its inheriting classes, and, of course, the methods of the interfaces it implements.
public method[] The Getdeclaredmethods () object represents all of the methods declared by the class or interface, including common, protected, default (package) access, and private methods, but does not include inherited methods. Of course, it also includes the method of the interface it implements.  For example, the above method information is printed by printing getdeclaredmethods MyClass:
Getvaluesetvalue
Let's see what happens with GetMethods printing: Test.java:
Import Java.lang.reflect.Method;    public class Test {public  static void Printmethodsmessage (Object obj) {  Class C = Obj.getclass ();    Method [] methods = C.getmethods (); for (Method method:methods) {      System.out.println (Method.getname ());   }  
public static void Main (String [] args) {MyClass MyClass = new MyClass (1);  Printmethodsmessage (MyClass); }}
Operation Result:
Getvaluesetvaluewaitwaitwaitequalstostringhashcodegetclassnotifynotifyall
Let's think about it: what "information" does a method deserve (or need) to analyze? Mainly two parts: 1. Returns a value of 2. Method parameters You may have guessed that the method object has provided a set of APIs to get this information, so let's take a look: Get the Class object for the method return value by Method.getreturntype ()
Import Java.lang.reflect.Method;  public class Test {public  static void Printmethodsmessage (Object obj) {  Class C = Obj.getclass (); Obtain the class object corresponding to the classes of obj  [] methods = C.getdeclaredmethods ();//Get an array of method objects for the methods in the class that obj belongs to  (method m   Ethod:methods) {//Traversal method Object   String name = Method.getname (); Get the method name   class Returnclass = Method.getreturntype ();//Get method return value corresponding to class object   String returnname = returnclass.ge  Tname ();  Gets the class name of the class to which the return value belongs--that is, the return value type      System.out.println (the return value type of the name + "method is" + Returnname);}  }  public static void Main (String [] args) {  MyClass MyClass = new MyClass (1);  Printmethodsmessage (MyClass);  }
}
Operation Result:
The return value type of the GetValue method is the return value type of the Intsetvalue method is void
With Method.getreturntype (), we get the class object that corresponds to the return value of the method (haha, after a circle or return to the class object) and then call the GetName method through the class object to get the name of the class to which the return value belongs. That is, the return value type gets the array Myclass.java of the class object of the method parameters by Method.getparametertypes ():
public class MyClass {public void method1 (int A, long b) {};  public void Method2 (float A, double b) {}; public void method3 (String str) {};}
Test.java:
 public class Test {public static void Printmethodsmessage (Object obj) {   Class C = Obj.getclass (); &nbs P Gets the class object corresponding to the classes that obj belongs to     method [] methods = C.getdeclaredmethods (); Gets an array of method objects that correspond to methods in the class that the obj belongs to     for (method Method:methods) {//Traversal method Object     S Tring MethodName = method.getname ();  //Get method name     String paramsstr = ""; //For holding a method parameter type List of strings     class [] paramsclasses = Method.getparametertypes ();    for (class Pc:paramsc      lasses) {String paramstr = Pc.getname ();//Gets the current parameter type PARAMSSTR+=PARAMSTR + " "; }    System.out.println (methodname+ "method for all parameters of the type list:" + Paramsstr); }} 
  public stat IC void Main (String [] args) {    MyClass MyClass = new MyClass ();    printmethodsmessage (M Yclass);   }}
Operation Result:
List of parameter types for the Method2 method: float double method1 the parameter type list for the method: int long method3 A list of parameter types for the method: Java.lang.String
Use the reflection API to parse the member variable information in the class to get the value of the class object that corresponds to the member variable type Myclass.java:
public class MyClass {private int number = 123; Private String name = "Peng Bay";}
Test.java:
Import Java.lang.reflect.field;import Java.lang.reflect.Method;  public class Test {public  static void Printfieldsmessage (Object obj) {  Class C = Obj.getclass ();  Gets the class object that corresponds to the classes that obj belongs to, try {      Field field = C.getdeclaredfield ("name"); Gets the Field object named Name      field.setaccessible (TRUE);//This step is very important!!! Set to True to access the value of the private member variable name!      String namevalue = (string) field.get (obj);//Gets the value      of the name member variable in obj  System.out.println (the value of the name member variable in the MyClass class is: "+ namevalue); Output  } catch (Nosuchfieldexception | SecurityException | IllegalArgumentException |  Illegalaccessexception e) {       //TODO auto-generated catch block        e.printstacktrace ();  }  
public static void Main (String [] args) { MyClass MyClass = new MyClass ();  Printfieldsmessage (MyClass); }
}
Operation Result:
The value of the name member variable in the MyClass class is: Peng Lake
The class object that reads the member variable type through the GetType method shows only the key two pieces of code:
Field field = Class1.getdeclaredfield (number "); System.out.print (Field.gettype (). GetName ());
Operation Result:
Int
"Note": Because of Java permissions, it is illegal to read the value of a private member variable directly (after adding field.setaccessible (true), but you can still read the private member variable's type directly when parsing the constructor using the Reflection API analysis class in the constructor information , in fact, the idea is generally consistent with the method of analysis, the key is to get the class of the parameter classes are different: 1. The constructor that gets the class declaration is used by the Getdeclaredconstructors method instead of Getdeclaredmethods Method 2. The constructor does not return a value, so you do not need to parse the return value (I seem to say nonsense ....) Don't say much nonsense, look at the following example: Myclass.java:
public class MyClass {public MyClass (int a, String str) {}}
Test.java:
 Import Java.lang.reflect.constructor;import Java.lang.reflect.field;import java.lang.reflect.method;  public class Test {public static void Printcontructorsmessage (Object obj) {   Class C = Obj.getclass ();   ; Gets the class object corresponding to the classes that obj belongs to     constructor [] constructors = c.getdeclaredconstructors ();     for (Constructor constructor:constructors) {    Class [] paramsclasses =  Constructor. Getparametertypes ();    String paramsstr = "";    for (Class pc:paramsclasses) {          String paramstr = Pc.getname ();    paramsstr+=paramstr + " ";    }    System.out.println ("A list of all parameters of the constructor:" + paramsstr); }}  public static void Main (String [] args) {    myclass MyClass = new MyClass (1, "Peng Bay");  &nbs P; printcontructorsmessage (MyClass);  } 
}
Operation Result:
List of types of all arguments to the constructor: int java.lang.String
Dynamically loading a class with reflection, and creating an instance object dynamic load class with this class when we use a class in the ordinary way, the class is statically loaded and uses Class.forName ("XXX") this way, it is dynamically loaded a class statically loaded class at compile time can determine whether the class exists, However, when loading a class dynamically, it is not possible to determine the existence of the class at compile time, but to determine if there is a class at runtime, so to catch a possible exception we can have a relatively intuitive understanding of the use of Eclipse: Eclipse can be compiled automatically when it is saved, so For example, if we use a class notexistclass that does not exist directly,

Once saved, you will be able to discover in the compile phase: "Eh?" It seems that there is no such class Oh! "The error of the report is:
Notexistclass cannot is resolved to a type
But what if we dynamically load a class with Class.forName ("XXX")? We found that, after saving, the error was not found in the compile phase, which is to catch an exception that might occur. Creating an instance object with the dynamically loaded class object has a newinstance method that we can use to create an instance object
Class classinstance = Class.forName ("MyPackage. MyClass "); MyClass MyClass = (MyClass) classinstance.newinstance ();

Note, however, that because Newinstance returns an object, it is forced to convert it to MyClass type.

After catching an exception that may be generated:
public class Test {public static void main (String [] args) {  try {       class classinstance = Class.forName ("MyPa Ckage. MyClass ");       MyClass MyClass = (MyClass) classinstance.newinstance ();     } catch (ClassNotFoundException e) {       //TODO auto-generated catch block       e.printstacktrace ();     } catch ( Instantiationexception e) {       //TODO auto-generated catch block       e.printstacktrace ();     } catch (   Illegalaccessexception e) {       //TODO auto-generated catch block       e.printstacktrace ();     } }}
Summary of the full text   If you have seen here, then allow me to use a little more wordy text to do a summary:  summary of  1. Reflection gives us the ability to analyze information in a comprehensive way, such as class methods, member variables and constructors, Reflection allows us to easily obtain this information, and the key to achieving this acquisition process is to obtain the class object, and then obtain the corresponding method object according to the class object, the Field object and the constructor object, and then obtain the information according to the respective API respectively. 2. Reflection also provides us with the ability to dynamically load classes   some details 1. The difference between getdeclaredxxx and getxxx in the API is that the former only obtains xxx (such as member variables or methods) of this class declaration, and does not get the inherited xxx in the superclass, which is the opposite of 2. API, GETXXXS (note the following s) returns an array, while the corresponding GetXXX ("key") key gets a value (this time because it might be reported to have checked the exception so it is wrapped with a try-catch statement) 3. Private member variables are not directly available to the value! Because Java itself is a protection mechanism that allows you to obtain the type of a private member variable, but does not allow direct fetch of the value, call Field.setaccessible (true) to the corresponding Field object to release the permission   
Reference: Using reflection to realize JavaBean automatic assignment import Java.lang.reflect.Method; Import java.util.*; Import Javax.servlet.http.HttpServletRequest; Import com.sns.exception.ApplicationException; Public final class Parameterutil {public static void Setformbean (HttpServletRequest request, Object Bean) {Class C = Bea N.getclass (); Method[] ms = C.getmethods ();     for (int i=0; i<ms.length; i++) {String name = Ms.getname ();      if (Name.startswith ("set")) {class[] cc = Ms.getparametertypes ();         if (cc.length==1) {String type = Cc[0].getname ();///parameter type try {//Get property name:         String prop = Character.tolowercase (Name.charat (3)) + name.substring (4);         Get parameter value:string param = getString (request, prop);          if (Param!=null &&!param.equals ("")) {//ms.setaccessible (true);          if (Type.equals ("java.lang.String")) {Ms.invoke (bean, new object[] {param}); } else if (type.equals ("int") | | | typE.equals ("Java.lang.Integer")) {Ms.invoke (bean, new object[] {new Integer (param)}); } else if (Type.equals ("Long") | | | type.equals ("Java.lang.Long")) {Ms.invoke (bean, new object[] {new Lon          g (param)}); } else if (Type.equals ("boolean") | | | type.equals ("Java.lang.Boolean")) {Ms.invoke (bean, new object[] {          Boolean.valueof (param)});           } else if (Type.equals ("Java.util.Date")) {Date date = Dateutil.parsedatetime (param);          if (date!=null) Ms.invoke (Bean, new object[] {date});       }}} catch (Exception e) {e.printstacktrace (); }}}}}} each time the Setxxx () method in JavaBean is found, the corresponding field xxx of the form is automatically searched, and if found, the corresponding field value is assigned to JavaBean by using reflection to call this method. Because the variable names and values passed by the form are all strings, some conversions are required. Currently, the data types that the program can handle include: boolean,boolean,int,integer,long,long,date, unsupported data types are automatically ignored. You can also easily add new types. Note that only the public's set method can be called. If you want the private or protected set method to be called, change the red-labeled GetMethods () to Getdeclaredmethods () to getAll methods, including private and protected, are stripped of ms.setaccessible (true), so that the private and protected methods can be called correctly. Reflection is a very powerful feature of the Java language, but because reflection destroys the object encapsulation and the reflection call is slower, it can only be used in the necessary tool classes.
Reference: "Java Core Technology Vol. 1"--cay S. Horstmann, Gary Cornell

A tentative study of Java reflection--"when class also learns to look in the mirror"

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.