Principles and application scenarios of Java reflection

Posted by ChaosXero on Tue, 21 Dec 2021 22:40:17 +0100

1, Static load class and dynamic load class

  • Statically loaded class: new creates an object, which is a statically loaded class. All possible classes need to be loaded at compile time

  • Dynamically loading classes: loading at run time

    Reflection is a mechanism for dynamically loading classes

2, Advantages and disadvantages of reflection

  • Advantages: judgment of runtime type and dynamic loading of classes: it improves the flexibility of code and can modify functions without modifying the source code
  • Disadvantages: there is a performance bottleneck: security checking and reflection are equivalent to a series of interpretation operations, which is slower than direct Java code

3, Understand the nature of generics through reflection

1. Generics only take effect during compilation

public class Test {
    public static void main(String[] args) {
        // 1. Verify generic erasure
        List  list1 = new ArrayList();
        List<String> list2 = new ArrayList<String>();
        System.out.println(list1.getClass()==list2.getClass());
    }
}
Copy code

Running result: true

2. Collection generics are used for type checking to avoid incorrect input

List<String> list2 = new ArrayList<String>();
list2.add("a");
list2.add(20);
Copy code

Compilation error: int cannot be converted to Java lang.String

3. You can bypass the checking of generics and add different types of elements through reflection

List<String> list2 = new ArrayList<String>();
list2.add("a");
Class<?> c = list2.getClass();
Method method = c.getDeclaredMethod("add",Object.class);
method.invoke(list2,20);
System.out.println(list2.size());
Copy code

Operation result: 2

It can be seen that since the type checking of generics is only effective at compile time, the dynamic loading principle of reflection can bypass the checking of generics and add different types of elements to the collection

4, Application of reflection

1. Load database driver

//  DriverManager.registerDriver(new com.mysql.cj.jdbc.Driver());
Class.forName("com.mysql.cj.jdbc.Driver");
Copy code

2. Loading configuration files such as xml or properties

  • Spring loads beans through XML configuration patterns

    • Load all XML or properties configuration files in the program into memory
    • The Java class parses the contents of xml or properties to obtain the bytecode string and related attribute information of the corresponding entity class
    • Use the reflection mechanism to obtain the Class instance of a Class according to this string
    • Dynamically configure the properties of an instance

    configuration file

    className=com.example.reflectdemo.TestInvoke
    methodName=printlnState
     Copy code

    Entity class

    public class TestInvoke {
        private void printlnState(){
            System.out.println("I am fine");
        }
    }
    Copy code

    Parsing profile content

    // Parse the contents of xml or properties to get the bytecode string and attribute information of the corresponding entity class
    public static String getName(String key) throws IOException {
        Properties properties = new Properties();
        FileInputStream in = new FileInputStream("D:\IdeaProjects\AllDemos\language-specification\src\main\resources\application.properties");
        properties.load(in);
        in.close();
        return properties.getProperty(key);
    }
    Copy code

    Use reflection to obtain the Class instance of the entity Class, create the instance object of the entity Class, and call the method

    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, IOException, ClassNotFoundException, InstantiationException {
        // Using the reflection mechanism, get the Class object from this string
        Class<?> c = Class.forName(getName("className"));
        System.out.println(c.getSimpleName());
        // Acquisition method
        Method method = c.getDeclaredMethod(getName("methodName"));
        // Bypass security checks
        method.setAccessible(true);
        // Create instance object
        TestInvoke testInvoke = (TestInvoke)c.newInstance();
        // Call method
        method.invoke(testInvoke);
    
    }
    
    Copy code

    Operation results:

Topics: Java Back-end