Java reflection mechanism (Miaodong Encyclopedia)

1. What is reflection?

 Reflection allows programmatic access to information about member variables, member methods, and constructors. .

Reflection is a mechanism. For any class, you can know all the properties and methods of this class. For any object, all properties and methods of this object can be called. This ability to dynamically obtain class information and dynamically call objects is called Java's reflection mechanism.

2. Three ways to obtain class objects

In Java, Class objects can be obtained in the following three ways, each of which has different usage scenarios:

1. Use the Class.forName() method: This method is suitable for use when you only know the fully qualified name string of the class. You can dynamically load the class and obtain the corresponding Class object. For example, when writing general code or specifying a class name string in a configuration file, you can use this method to obtain the Class object.

try {
    Class<?> cls = Class.forName("java.lang.String");
} catch (ClassNotFoundException e) {
    e.printStackTrace();
}

2. Use .class syntax: This method is suitable for when we clearly know the type of a certain class. We can directly use the class name plus the .classsuffix to get the corresponding Class object. For example, when creating an instance and determining whether a class is a subclass of a specific class, you can use this method to obtain the Class object. 

Class<?> cls = String.class;

 3. Use the getClass() method of the object: This method is suitable for objects that already exist and whose corresponding Class object needs to be obtained. For example, when performing object comparison, type judgment, or dynamically calling object methods, you can use this method to obtain the Class object.

String str = "Hello";
Class<?> cls = str.getClass();

3. Reflection acquisition construction method

Using reflection to obtain the constructor can be achieved by following these steps:

  1. Get the Class object: First, you need to get the Class object of the target class. You can use one of the three methods mentioned above to obtain the Class object.

  2. Call the getConstructors() or getDeclaredConstructors() method: You can call the getConstructors() method or getDeclaredConstructors() method through the Class object to obtain the constructor array. These two methods return public and all constructors (including private and protected constructors) respectively.

  3. Traverse the constructor array: After obtaining the constructor array, you can use loop traversal to obtain the detailed information of each constructor.

  4. Call the relevant methods of the Constructor class: For each constructor, you can operate it through the methods of the Constructor class, such as getName() to get the constructor name, getModifiers() to get the modifiers, getParameterTypes() to get the parameter types, etc.

Here is a sample code that demonstrates how to use reflection to obtain the constructor method:

import java.lang.reflect.Constructor;
import java.util.Arrays;

public class Main {
    public static void main(String[] args) {
        try {
            // 步骤1:获取Class对象
            Class<?> cls = MyClass.class;
            
            // 步骤2:获取构造方法数组
            Constructor<?>[] constructors = cls.getDeclaredConstructors();
            
            // 步骤3:遍历构造方法数组
            for (Constructor<?> constructor : constructors) {
                // 步骤4:调用Constructor类的相关方法
                String name = constructor.getName();
                int modifiers = constructor.getModifiers();
                Class<?>[] parameterTypes = constructor.getParameterTypes();
                
                System.out.println("Constructor Name: " + name);
                System.out.println("Modifiers: " + modifiers);
                System.out.println("Parameter Types: " + Arrays.toString(parameterTypes));
                System.out.println();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

class MyClass {
    public MyClass() {
    }
    
    private MyClass(int value) {
    }
}

Output result:

Constructor Name: MyClass
Modifiers: 1
Parameter Types: []

Constructor Name: MyClass
Modifiers: 2
Parameter Types: [int]

4. Obtain member variables by reflection

To use reflection to obtain member variables, you can follow these steps:

  1. Get the Class object of the target class: Get the Class object of the target class through Class.forName()method, obj.getClass()method or directly using the class name.class. Assume that the target class is MyClass.

  2. Use the Class object to obtain member variables: obtain the member variable object by calling getField()the method or methods of the Class object . getDeclaredField()These methods are used to obtain public member variables and all member variables (including private member variables) respectively.

  3. get()Manipulate member variables: Get the value of the member variable through the method of the member variable object , or set()set the new value of the member variable through the method.

The following is a sample code that demonstrates how to use reflection to obtain member variables and operate on it:

import java.lang.reflect.Field;

public class Main {
    public static void main(String[] args) {
        try {
            // 步骤1:获取目标类的Class对象
            Class<?> cls = MyClass.class;

            // 步骤2:获取成员变量
            Field field = cls.getDeclaredField("name");

            // 步骤3:操作成员变量
            // 设置访问权限
            field.setAccessible(true);

            // 获取成员变量的值
            Object instance = cls.newInstance();
            Object value = field.get(instance);
            System.out.println("原始值:" + value);

            // 设置新值
            field.set(instance, "New Value");
            System.out.println("修改后的值:" + field.get(instance));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

class MyClass {
    private String name = "Original Value";
}

Running the above example code will output the following results:

原始值:Original Value
修改后的值:New Value

In the example, first MyClass.classobtain the Class object of the target class MyClass. Then use the method of the Class object getDeclaredField()to obtain the Field object of the private member variable named "name". Next, set access permissions through the Field object's setAccessible(true)methods to allow access to private member variables. Finally, get the value of the member variable through the Field object's get()method and set()set the new value through the method.

Please note that exceptions may be thrown during the process of obtaining and operating member variables, such as NoSuchFieldException, IllegalAccessException, etc., and exceptions need to be handled appropriately.

Obtaining member variables through reflection can dynamically access and modify the attribute values ​​​​of the object at runtime, which is very useful for some specific demand scenarios. But use it with caution and avoid abusing the reflection mechanism.

5. Reflection acquisition method

 Here is a sample code that demonstrates how to use reflection to obtain a member method and call it:

import java.lang.reflect.Method;

public class Main {
    public static void main(String[] args) {
        try {
            // 步骤1:获取目标类的Class对象
            Class<?> cls = MyClass.class;

            // 步骤2:获取成员方法
            Method method = cls.getDeclaredMethod("printMessage", String.class);

            // 步骤3:调用成员方法
            Object instance = cls.newInstance();
            method.invoke(instance, "Hello, Reflection!");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

class MyClass {
    private void printMessage(String message) {
        System.out.println("Message: " + message);
    }
}

Running the above example code will output the following results:

Message: Hello, Reflection!

In the example, first MyClass.classobtain the Class object of the target class MyClass. Then use the method of the Class object getDeclaredMethod()to obtain the Method object of the private member method named "printMessage". Next, invoke()the member method is called through the method of the Method object.

6. Summary

 

Java reflection is a powerful mechanism that allows members of a class (including constructors, fields, and methods) to be dynamically obtained and manipulated at runtime. Here is a summary of Java reflection:

  1. Get the Class object: Get the Class object of the target class through Class.forName()method, obj.getClass()method or directly using the class name.class.

  2. Obtain the constructor method: Obtain the constructor method object by calling getConstructor()the method or method of the Class object . getDeclaredConstructor()These methods are used to obtain public constructors and all constructors (including private constructors) respectively.

  3. Create an instance object: newInstance()Create an instance object of the constructor method through the method of the constructor method object.

  4. getField()Obtain member variables: Obtain the member variable object by calling the method or method of the Class object getDeclaredField(). These methods are used to obtain public member variables and all member variables (including private member variables) respectively.

  5. get()Manipulate member variables: Get the value of the member variable through the method of the member variable object , or set()set the new value of the member variable through the method.

  6. Get member methods: Get the member method object by calling getMethod()the method or methods of the Class object . getDeclaredMethod()These methods are used to obtain public member methods and all member methods (including private member methods) respectively.

  7. Calling member methods: invoke()Calling member methods through the methods of the member method object.

Through reflection, you can dynamically obtain and operate members of a class at runtime. It provides great flexibility and can be applied to many scenarios, such as dependency injection, ORM framework, dynamic proxy, etc.

However, reflection needs to be used with caution as it can cause performance penalties and in some special cases may break encapsulation and security. Therefore, you should follow best practices when using reflection and weigh the pros and cons where necessary.

Guess you like

Origin blog.csdn.net/weixin_55772633/article/details/132380477