Java reflection mechanism in detail

  • 2020-04-01 04:28:32
  • OfStack

This article has analyzed the Java reflection mechanism in detail. Share with you for your reference, as follows:

1. Prior knowledge (Java virtual machine)

Method area of the Java virtual machine:

The Java virtual machine has a runtime data area, which is divided into the method area, the heap area, and the stack area. The main function of the method area is to store the type information of the loaded classes. When the Java virtual machine loads a certain type, the class loader needs to locate the corresponding class file and read it into the Java virtual machine. The virtual machine then extracts the type information in the class and stores the information in the method area. This information mainly includes:

1. Fully qualified name of this type

The fully qualified name of the direct superclass of this type

3. Is this type a class type or an interface type

4. Access modifier of this type

5. Ordered list of fully qualified names of any direct superinterface

6. Constant pool of this type

7. Field information

8. Method information

All class variables except constants

10. A reference to the class class

Etc. (readers can refer to the description in the book "in depth with the Java virtual machine")

Class Class:

The Class Class is a very important Java base Class. Each time a new type is loaded, the Java virtual machine creates a Class instance in the Java heap that corresponds to the new type, which represents the type, and through that Class instance we can access the basic information of that type. As mentioned above, the type information of a loaded Class is stored in the method area, which we can access through the Class instance. For example, there are corresponding methods in the above mentioned information Class, as follows:

1, the getName (); The fully qualified name of this type

2, getSuperClass (); The fully qualified name of the direct superclass of this type

3, isInterface (); Is this type a class type or an interface type

4, getTypeParamters (); Access modifier for this type

5, getInterfaces (); An ordered list of fully qualified names for any direct superinterface

6, the getFields (); Field information

7, getMethods (); Methods information

Etc. (you can refer to the JDK help documentation for more information)

Second, Java reflection details

Reflection: the concept of the so-called reflection is the Java language at runtime has a from the view of ability, reflection gives your program code can be loaded into the JVM classes in the internal information, allows you to execute a program to get to class inside information, rather than at the time of writing the code will have to know the inside information of classes required, this makes the reflection of building flexible application of the main tools.

Common reflection classes and functions :Java reflection mechanism is implemented with the help of four classes: Class, Constructor, Field, Method; Class represents the class object, constructor-class Constructor object, field-class attribute object, and method-class Method object. Through these four objects, we can roughly see each component of a class. At the heart of this is the Class Class, which is the basis for reflection, and which contains the methods that we described in the first part. When applying reflection, we are most concerned with the constructor, attributes, and methods of a Class. Next, we will focus on the methods for these three elements in the Class Class:

1. Method of obtaining constructor

Constructor getConstructor(Class[] params) - gets a common Constructor that USES a special argument type,

Constructor[] getConstructors() -- gets all the common constructors of the class

Constructor getDeclaredConstructor(Class[] params) -- gets a Constructor that USES a specific parameter type (regardless of the access level)

Constructor[] getDeclaredConstructors() -- gets all constructors of the class (regardless of the access level)

2. Methods to obtain field information

Field getField(String name) - gets the named public Field

Field[] getFields() -- gets all the public fields of the class

Field getDeclaredField(String name) - gets the named Field of the class declaration

Field[] getDeclaredFields() -- gets all the fields of the class declaration
3. Methods to obtain method information

Method getMethod(String name, Class[] params) -- gets a named public Method using a specific parameter type

Method[] getMethods() -- gets all the public methods of the class

Method getDeclaredMethod(String name, Class[] params) -- a Method that gets the named Method of the Class declaration, using the parameter type of the feature

Method[] getDeclaredMethods() -- get all methods declared by the class

Basic steps for applying reflection:

1. Get the Class object of the Class you want to operate on;

Method 1 :Classc= class.forname (" java.lang.string ") // this way to get the Class object of the Class requires the package name

Method 2: for primitive data types, you can use statements like Class c=int. Class or Class c=Integer.TYPE

Method 3 :Class c= myclass.class

2. Call the method in Class to get the information set you want, such as call the getDeclaredFields() method to get all the attributes of the Class;

3. Process the information from step 2 and do what you want to do.

Reflection example:

I'll show you how reflection works with three examples of class constructors, properties, and methods.

1. Constructors

The steps are: get a constructor for a class through reflection, and then call that constructor to create an instance of that class


import java.lang.reflect.*; 
public class ConstructorDemo{ 
  public ConstructorDemo(){ } 
  public ConstructorDemo(int a, int b){ 
   System.out.println("a="+a+"b="+b); 
  } 
  public static void main(String args[]){ 
    try { 
      Class cls =Class.forName(" The package name .ConstructorDemo"); 
      Class partypes[] =new Class[2]; partypes[0] = Integer.TYPE;  
      partypes[1] =Integer.TYPE; 
      Constructor ct=cls.getConstructor(partypes); 
      Object arglist[] =new Object[2]; 
      arglist[0] = newInteger(37); 
      arglist[1] = newInteger(47); 
      Object retobj = ct.newInstance(arglist); 
     } catch (Throwable e) {
      System.err.println(e);} 
     } 
  } 

2, attributes,

The steps are: get an attribute of a class through reflection, and then change the value of that attribute corresponding to an instance of that class


import java.lang.reflect.*; 
public class FieldDemo1{ 
 public double d; 
 public static void main(String args[]){ 
 try { 
  Class cls = Class.forName("FieldDemo1"); 
  Field fld = cls.getField("d"); 
  FieldDemo1 fobj = new FieldDemo1(); 
  System.out.println("d = " + fobj.d); 
  fld.setDouble(fobj, 12.34); 
  System.out.println("d = " + fobj.d); 
 } catch (Throwable e){ 
  System.err.println(e); } 
 } 
} 

3, methods,

The steps are: get a method of a class by reflection mechanism, and then call the method corresponding to an instance of the class


//A method is called by using its name
import java.lang.reflect.*; 
public class MethodDemo1{ 
 public int add(int a, int b){ 
 return a + b; 
 } 
 public static void main(String args[]){ 
  try { 
   Class cls =Class.forName("MethodDemo1"); 
   Class partypes[] = new Class[2]; 
   partypes[0] = Integer.TYPE; 
   partypes[1] = Integer.TYPE; 
   Method meth = cls.getMethod("add",partypes); 
   MethodDemo1 methobj = new MethodDemo1(); 
   Object arglist[] = new Object[2]; 
   arglist[0] = new Integer(37); 
   arglist[1] = new Integer(47); 
   Object retobj= meth.invoke(methobj, arglist); 
   Integer retval = (Integer)retobj; 
   System.out.println(retval.intValue()); 
  } catch (Throwable e) { 
   System.err.println(e); 
  } 
 } 
}

Iii. Application of Java reflection (Hibernate)

In the second part, we gave a more systematic explanation of Java reflection and gave a few simple examples. Now we will discuss the specific application of Java reflection. As we've already seen, Java reflection provides a versatile way to dynamically link program components, allowing programs to create and control objects of any class (subject to security restrictions) without having to hard-code the target class in advance. These characteristics make reflection particularly useful for creating libraries that work with objects in a very generic way. For example, reflection is often used in frameworks that continuously store objects in a database, XML, or other external format. Here we have Hibernate framework as an example to illustrate the importance of reflection.

Hibernate is a Java framework that shields JDBC and implements ORM. With this framework, we can get rid of tedious SQL statements and use the save() method of the Session class in Hibernate to directly save the object of a class to the database, that is, the code involved in the SQL statement. Hibernate does it for us. Here comes the question: how does Hibernate know what properties an object it wants to store has? What are the types of these properties? So how does it construct the SQL statement when it stores the object's attributes to the database? The solution to this problem is our Java reflection!

Let's take an example to illustrate. For example, we define a User class, which has 20 properties and their get and set methods. Correspondingly, there is a User table in the database, which corresponds to 20 fields. Suppose we extracted a record from the User table, and now we need to assign the contents of the 20 fields of this record to the 20 attributes of a User object myUser. However, the Hibernate framework does not know this User class when compiling, and it cannot directly call the myuser.getxxx or myuser.setxxx methods.

1. Construct the PreparedStament statement based on the query criteria, which returns the values of 20 fields;

2. Hibernate gets the list of attributes of the User class (which is a String array) and the types of these attributes by reading the configuration file;

3. Create the Class object c of the Class to which myUser belongs; C = myUser. GetClass ();

4. Construct a for loop, and the number of loops is the length of the list;

4.1 read the value of list[I] and then construct the set method for the corresponding attribute;

4.2 determine the type XXX of list[I], and call getXXX(I) in the PreparedStament statement to get the value of the column I.

4.3 take the value obtained in 4.2 as the parameter of the set method obtained in 4.1, so as to complete the assignment of a field like a property, so as to loop;

See, that's what reflection does, and without reflection it's hard to imagine how hard it would be to do the same thing! However, reflection also has disadvantages, such as low performance, more complex security, etc., which will not be discussed here, interested readers can find the answer on the Internet, there are many!

I hope this article has been helpful to you in Java programming.


Related articles: