In depth understanding of reflection class loading mechanism

catalogue

What is reflection?

Use reflection to get Class object

Class class

Common methods of Class

How to get Class

Class loading and ClassLoader

Class loader

Extension: parental delegation mechanism

Get properties of reflection class (file, method, constructor)

Create dynamic objects with reflections

What is reflection?

 

 

 

Use reflection to get Class object

public class Test {
    public static void main(String[] args) throws ClassNotFoundException {
        //Use reflection to get class objects
        Class c1= Class.forName("com.wjc.User");
        Class c2= Class.forName("com.wjc.User");
        Class c3= Class.forName("com.wjc.User");

        //A Class has only one Class object in memory
        //After a Class is loaded, the whole structure of the Class will be encapsulated in the Class object
        System.out.println(c1.hashCode());
        System.out.println(c2.hashCode());
        System.out.println(c3.hashCode());

    }
}

Class class

The information that can be obtained after the object looks in the mirror: the properties, methods and constructors of a Class, and which interfaces a Class implements. For each Class, the JRE keeps an object of the same Class type for it. A Class object contains information about a specific structure (Class / interfaceenum / annotation / primitive type / void /).

Class itself is also a class

Class object can only be created by the system. We can only get this object through reflection

A loaded Class will only have one Class instance in the JVM

A class object corresponds to one loaded into the JVM Class file

Each Class instance will remember which Class instance it was generated from

All loaded structures in a Class can be completely obtained through Class

Class is the root of Reflection. For any class you want to dynamically load and run, you have to obtain the corresponding class object first

Common methods of Class

How to get Class

public class Test {
    public static void main(String[] args) throws ClassNotFoundException {
        //A Class has only one Class object in memory
        //After a Class is loaded, the whole structure of the Class will be encapsulated in the Class object

        //Method 1: get Class through object
        User user=new UserImpl();
        Class c1 = user.getClass();
        System.out.println(c1.hashCode());        //1554874502
        //Method 2: use reflection to obtain class objects
        Class c2= Class.forName("com.wjc.UserImpl");
        System.out.println(c2.hashCode());           //1554874502

        //Method 3: get class by class name
        Class c3 = UserImpl.class;
        System.out.println(c3.hashCode());           //1554874502

        //The eight basic types of wrapper classes have Type methods
        Class<Integer> type = Integer.TYPE;
        Class<Double> type1 = Double.TYPE;
        System.out.println(type);         //int
        System.out.println(type1);        //double

        //Gets the parent class of the class
        Class superclass = c1.getSuperclass();
        System.out.println(superclass);          //class com.wjc.User

        //A Class has only one Class object in memory
        //After a Class is loaded, the whole structure of the Class will be encapsulated in the Class object


    }
}

public class Test02 {
    public static void main(String[] args) {
        Class c1 = Object.class;   //class
        Class c2 = Comparable.class;   //Interface
        Class c3 = String[].class;  //array
        Class c4 = int[][].class;  //Two dimensional array
        Class c5 = Override.class;  //annotation
        Class c6 = Integer.class;  //Packaging
        Class c7= ElementType.class;  //Enumeration class
        Class c8=void.class;   //void
        Class c9=Class.class;   //Class itself is also a class

        System.out.println(c1);
        System.out.println(c2);
        System.out.println(c3);
        System.out.println(c4);
        System.out.println(c5);
        System.out.println(c6);
        System.out.println(c7);
        System.out.println(c8);
        System.out.println(c9);

        //As long as the element type is the same as the dimension, it is the same Class
        int a[]=new int[10];
        int b[]=new int[100];
        System.out.println(a.getClass().hashCode());  //1554874502
        System.out.println(b.getClass().hashCode());   //1554874502

    }
}

Class loading and ClassLoader

 

When initializing a subclass, if it is found that its parent class has not been initialized, it is necessary to trigger the initialization of its parent class first

When creating an instance of a class (for example: new keyword, through reflection, cloning, deserialization)

When the calling class is a static method (that is, when the bytecode invokestatic instruction is used)

When using static fields of classes and interfaces (special consideration for final modification) (for example, getstatic or putstatic instructions)

If an interface defines a default method, the class that directly or indirectly implements the interface should be initialized before it

When the MethodHandle instance is initially called, initialize the class () of the method pointed to by the MethodHandle

 . class will not initialize why Class does not cause class initialization - CSDN Forum

public class Test03 {
    static {
        System.out.println("Main Be loaded");
    }

    public static void main(String[] args) throws  Exception{
        int m = Son.m;    //Subclasses and superclasses are initialized

        int m1 = Son.M;   //Neither the subclass nor the parent class is initialized, and M is a constant

        int m2=Son.b;       //The parent class is initialized, but the child class is not initialized. The child class references the static variable of the parent class, which will not lead to the initialization of the child class


        //1. Active quotation
        Son son=new Son();

        //Reflection also produces active references
       Class.forName("com.wjc.Son");

       Class sonClass = Son.class;  //Can't initialize the class. Why?
        Son.class.newInstance();  //Class is initialized. Why?

    }
}

class  Father{
    static  int b=2;
    static {
        System.out.println("Parent class loaded");
    }
}

class Son extends Father{
    static {
        System.out.println("Subclass loaded");
    }
    static int m=100;
    static  final  int M=1;
}

. class will not initialize why Class does not cause class initialization - CSDN Forum

Class loader

 

 

 

 

 

public class Test04 {
    public static void main(String[] args) throws  Exception{
        //Gets the loader of the system class
        ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
        System.out.println(systemClassLoader);   //sun.misc.Launcher$AppClassLoader@18b4aac2

        //Get the parent class loader -- > extension class loader of the system class loader
        ClassLoader parent = systemClassLoader.getParent();
        System.out.println(parent);              //sun.misc.Launcher$ExtClassLoader@5cad8086

        //Get the parent class loader -- > root loader of the extension class loader (c/c + +)
        //java can't get it. null is printed out
        ClassLoader parent1 = parent.getParent();
        System.out.println(parent1);             //null

        //Test which loader the current class is
        ClassLoader loader = Class.forName("com.wjc.UserImpl").getClassLoader();
        System.out.println(loader);         //System class loader, printed as sun misc. Launcher$ AppClassLoader@18b4aac2

        ClassLoader loader2 = Class.forName("java.lang.Object").getClassLoader();
        System.out.println(loader2);          //The root is loaded and unloaded, and the print is null


//Print the path that the classloader can load
        System.out.println(System.getProperty("java.class.path"));
        /*
        C:\Users\86153\.jdks\corretto-1.8.0_312\jre\lib\charsets.jar;
        C:\Users\86153\.jdks\corretto-1.8.0_312\jre\lib\ext\access-bridge-64.jar;
        C:\Users\86153\.jdks\corretto-1.8.0_312\jre\lib\ext\cldrdata.jar;
        C:\Users\86153\.jdks\corretto-1.8.0_312\jre\lib\ext\dnsns.jar;
        C:\Users\86153\.jdks\corretto-1.8.0_312\jre\lib\ext\jaccess.jar;
        C:\Users\86153\.jdks\corretto-1.8.0_312\jre\lib\ext\jfxrt.jar;
        C:\Users\86153\.jdks\corretto-1.8.0_312\jre\lib\ext\localedata.jar;
        C:\Users\86153\.jdks\corretto-1.8.0_312\jre\lib\ext\nashorn.jar;
        C:\Users\86153\.jdks\corretto-1.8.0_312\jre\lib\ext\sunec.jar;
        C:\Users\86153\.jdks\corretto-1.8.0_312\jre\lib\ext\sunjce_provider.jar;
        C:\Users\86153\.jdks\corretto-1.8.0_312\jre\lib\ext\sunmscapi.jar;
        C:\Users\86153\.jdks\corretto-1.8.0_312\jre\lib\ext\sunpkcs11.jar;
        C:\Users\86153\.jdks\corretto-1.8.0_312\jre\lib\ext\zipfs.jar;
        C:\Users\86153\.jdks\corretto-1.8.0_312\jre\lib\jce.jar;
        C:\Users\86153\.jdks\corretto-1.8.0_312\jre\lib\jfr.jar;
        C:\Users\86153\.jdks\corretto-1.8.0_312\jre\lib\jfxswt.jar;
        C:\Users\86153\.jdks\corretto-1.8.0_312\jre\lib\jsse.jar;
        C:\Users\86153\.jdks\corretto-1.8.0_312\jre\lib\management-agent.jar;
        C:\Users\86153\.jdks\corretto-1.8.0_312\jre\lib\resources.jar;
        C:\Users\86153\.jdks\corretto-1.8.0_312\jre\lib\rt.jar;
        D:\Javaproject\spring-study\ReflectionDemo\target\classes;
        D:\apache-maven-3.8.1\repository\org\springframework\spring-webmvc\5.3.15\spring-webmvc-5.3.15.jar;
        D:\apache-maven-3.8.1\repository\org\springframework\spring-aop\5.3.15\spring-aop-5.3.15.jar;
        D:\apache-maven-3.8.1\repository\org\springframework\spring-beans\5.3.15\spring-beans-5.3.15.jar;
        D:\apache-maven-3.8.1\repository\org\springframework\spring-context\5.3.15\spring-context-5.3.15.jar;
        D:\apache-maven-3.8.1\repository\org\springframework\spring-core\5.3.15\spring-core-5.3.15.jar;
        D:\apache-maven-3.8.1\repository\org\springframework\spring-jcl\5.3.15\spring-jcl-5.3.15.jar;
        D:\apache-maven-3.8.1\repository\org\springframework\spring-expression\5.3.15\spring-expression-5.3.15.jar;
        D:\apache-maven-3.8.1\repository\org\springframework\spring-web\5.3.15\spring-web-5.3.15.jar;
        D:\IntelliJ IDEA 2021.1.3\lib\idea_rt.jar
         */
    }
}

Extension: parental delegation mechanism

The parent delegation mechanism probably looks up the package after creating the object, but it can't find its own. If you write a String class, it will not take effect. The parent delegation mechanism ensures that the core class is not destroyed

Get properties of reflection class (file, method, constructor)

 

//Use reflection to get class information
public class Test05 {
    public static void main(String[] args) throws  Exception{

        Class c1 = Class.forName("com.wjc.User");

        //Get the name of the class
        System.out.println(c1.getName());   //Package name + class name com wjc. User
        System.out.println(c1.getSimpleName());   //Class name User
        
        //Get the properties of the class
        Field[] fields = c1.getFields();   //Only public decorated fields can be found
        for (Field field : fields) {
            System.out.println(field);
        }

        Field[] declaredFields = c1.getDeclaredFields();   //Find all fields
        for (Field declaredField : declaredFields) {
            System.out.println(declaredField);

        }
        c1.getField("name");   //Gets the specified public decorated field
        c1.getDeclaredField("name");// Get the field with the specified name, unlimited

        System.out.println("=================================");

        c1.getMethods();   //Find the method of public modification
        c1.getDeclaredMethods();  //Find all the ways

        c1.getMethod("getName",null);   //The method to get the specified public modification must be given the type of its parameter, otherwise it cannot be recognized, and overload should be considered
        c1.getMethod("setName",String.class);   //Gets the method of the specified public modifier

        System.out.println("=================================");
        c1.getConstructor();   //Get public modified constructor
        c1.getDeclaredConstructor();  //Get all constructors

        c1.getDeclaredConstructor(String.class, String.class);  //Gets the specified constructor



    }
}

Create dynamic objects with reflections

 

Tags: Java programming language

Posted by angel_cowgirl on Sun, 15 May 2022 01:05:42 +0300