Reflect ion in JAVA

1: Class loading

Class life cycle in memory: load -- > use -- > unload

1.1: class loading process

(1) Loading: load

Refers to reading clas bytecode data of type into memory. Get the binary data stream of the class through the full name of the class.

The binary data stream of the parsing class is the data structure in the method area

Create an instance of the java.lang.Class class class to represent the type. As the access entry of various data of this class in the method area

(2) Connection: link           Prepare: prepare the corresponding memory

Prepare the corresponding memory (method area), create Class objects, assign default values to Class variables and initial values to static constants.

Parsing: converts symbolic references to classes, interfaces, fields, and methods to direct references

(3) Initialization: initialize

1.2: class loader

Different classes need different class loaders to load

1. Boot class loader Bootstrap
    Load core class library String Integer
    jre/lib  rt.jar  String Math
     It is not implemented in Java code, nor is it a subclass of ClassLoader. When obtaining its object, it often returns null

2. Extension class loader ExtClassLoader
    jre/lib/ext/ *jar


3. Application Loader AppClassLoader
    Self written class animal cat dog student

4. Custom class loader
      For example: tomcat

be careful:

Get the class loader 1. Get the class loader using the runtime type 2. Use the runtime type. getClassLoader(); 3. The father of the application loader is the extension class loader. The father of the extension class loader is the boot class loader. 4. Parental delegation

1.3: acquisition of class loader

To obtain the Class loader, first obtain the runtime Class (getClass(), etc.) to obtain large Class objects, and then obtain the Class loader (getClassLoader()) according to the runtime Class

 @Test
    public void test04(){

        Person person = new Person();
        Class<? extends Person> aClass = person.getClass();
        ClassLoader classLoader = aClass.getClassLoader();
        System.out.println("Application Loader  = " + classLoader);//AppClassLoader

        ClassLoader extClassLoade = classLoader.getParent();//ExtClassLoade
        System.out.println("parent = " + extClassLoade);

        ClassLoader parent = extClassLoade.getParent();

        System.out.println("parent = " + parent);//null

    }
    @Test
    public void test03(){
        Person person = new Person();
        //Get application class loader
        Class<? extends Person> aClass = person.getClass();
        ClassLoader classLoader = aClass.getClassLoader();
        System.out.println("classLoader = " + classLoader);
    }

    @Test
    public void test02() throws ClassNotFoundException {
        //1. Get boot class loader
        Class<?> aClass = Class.forName("com.sun.nio.zipfs.ZipCoder");
        //extensions class loader 
        ClassLoader classLoader = aClass.getClassLoader();
        System.out.println("classLoader = " + classLoader);
        //Get boot class loader
        ClassLoader parent = classLoader.getParent();
        System.out.println("parent = " + parent);
    }
    @Test
    public void test01(){
        //1: Get boot class loader
        //Because the String is under the core package, it is loaded by the boot class loader
        String s = "Hello";
        //Get runtime type
        Class<? extends String> aClass = s.getClass();
        //Get loader
        ClassLoader classLoader = aClass.getClassLoader();
        // The boot class loader itself is not implemented in Java code, nor is it a subclass of ClassLoader. When obtaining its object, it often returns null
        System.out.println("classLoader = " + classLoader);

    }

2: Class initialization:

Initialization: assign values to static member variables in the class
        1. Static member variable display assignment statement
        2. Static code block content

2.1: what operations will cause class initialization?

(1) To run the class where the main method is located, first complete the class initialization, and then execute the main method

(2) Create this type of object

(3) Call the static members (class variables and class methods) of a class. If the class is not initialized, complete the class initialization first  

(4) As long as a subclass needs to be initialized during inheritance, if it is found that its parent class has not been initialized, the parent class must be initialized first.

(5) When a class is operated through reflection, if the class is not initialized, it will also cause the class to initialize first  

Class initialization executes < clinit > (), which consists of (1) the explicit assignment code of class variables (2) the code in the static code block

public class Person {
    public final static double salary  =9999.9;

    static  int age = 20;

    static {
        System.out.println("this is Person static Code block");
    }

    public void add(){


    }

    public static void show(){

        System.out.println("this is static show()");
    }

    public static void main(String[] args) {

    }
}
class Son extends Person{

    static {
        System.out.println("this is Son static Code block");
    }

    static  double weight = 100.0;

    public static void showMessage(){

        System.out.println("this is son static  showMessage()");
    }

}
Some operations have initialization lag?
    Initialization lag: the use of resources does not lead to the initialization of this class (it needs to be understood according to the loading order of resources. If it is loaded and called with the class information, it may cause the class after initialization)
 @Test
    public void test02(){
        //When a subclass directly calls the static resources of the parent class, the instantiation of the subclass will lag
        //Because class loading takes precedence over instantiation, the information of parent and child classes has been loaded
        //And the static resources are also loaded with the loading of the class, so the subclass does not need to be initialized at this time
//           Son.show();

        //Calling constant information directly by the parent class name will also cause the initialization of the parent class to lag
        //Because constants are determined at the join stage
        /*double age = Person.salary;
        System.out.println("age = " + age);*/
        //Creating an array of classes will also cause after class initialization
        Person[] ps = new Person[3];

    }

    @Test
    public void test01() throws ClassNotFoundException {
        //Reflection can cause the parent class to initialize and then the child class to initialize
//        Class<?> aClass = Class.forName("com.atguigu.load.Son");
        //Parent class instance
//        Person person = new Person();
        //Advanced class initialization, code in the execution method.
//         Person.show();
        Son.showMessage();
        System.out.println("------");
        Son.showMessage();


    }

3: parents delegate mode of Java system class loader

If the Class loader at the next level receives a task, it will first search whether it has been loaded. If not, it will upload the task first. If it has not been loaded, it will go all the way to the root loader. If the root loader is not found in its responsible path, it will send back. If it is not found all the way back to the last level, it will report ClassNotFoundException or NoClassDefError, If it is found at a certain level, it directly returns the Class object.

1. The advantage of adopting the two parent delegation mode is that the Java class has a hierarchical relationship with priority along with its class loader. Through this hierarchical relationship, the repeated loading of the class can be avoided. When the father has loaded the class, it is not necessary to load the child ClassLoader again.
2. Safe. The types defined in the Java core API will not be replaced at will. Suppose a class named java.lang.Integer is passed through the network and passed to the startup class loader through the parental delegation mode. The startup class loader finds the class with this name in the core Java API and finds that the class has been loaded, and will not reload the java.lang.Integer passed through the network, And directly return the loaded Integer.class, which can prevent the core API library from being tampered with at will.

The application class loader regards the extension class loader as the parent loader,

The extension class loader treats the boot class loader as the parent loader.

4: Uninstall of class:

1: All instances of this class have been recycled;

2: The ClassLoader that loaded this class has been recycled

3:     The java.lang.Class object corresponding to this class is not referenced anywhere, and the methods of this class cannot be accessed anywhere through reflection.

If the above three conditions are met, the JVM will perform GC garbage collection

5: javalang.Class class

5.1: java reflection mechanism

Java reflection mechanism is to know all the properties and methods of any class in the running state; For any object, you can call any of its methods and properties; This kind of dynamically obtained information and the function of dynamically calling object methods are called the reflection mechanism of Java language.

The Class object is the source of reflection.

5.2: which types can get Class objects

All runtime types

//(1) Basic data type and void
For example: int.class
     void.class
//(2) Classes and interfaces
For example: String.class
    Comparable.class
//(3) Enumeration
For example: ElementType.class
//(4) Annotation
For example: Override.class
//(5) Array
For example: int[].class

5.3: four ways to obtain Class objects:

(1) Type name.class     All types

(2) Object. getClass()

(3) Class. Forname (full name of type)

(4) ClassLoader's ClassLoader object. Loadclass (type full name)

 @Test
    public void test04() throws ClassNotFoundException {
        Class catClass = Cat.class;

        ClassLoader classLoader = catClass.getClassLoader();

        //It is cumbersome. This method is generally not used
        Class<?> aClass = classLoader.loadClass("com.atguigu.clazz.Dog");

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


    }
    @Test
    public void test03() throws ClassNotFoundException {
        Class<?> aClass = Class.forName("com.atguigu.load.Person");
        System.out.println("aClass = " + aClass);


    }
    @Test
    public void test02(){
        Class<String> stringClass = String.class;
        System.out.println("stringClass = " + stringClass);
        Class<Integer> integerClass = int.class;
        System.out.println("integerClass = " + integerClass);
        Class<Void> voidClass = void.class;
        System.out.println("voidClass = " + voidClass);

        Class<int[][]> aClass = int[][].class;
        System.out.println("aClass = " + aClass);

    }


    @Test
    public void test01(){
        Dog dog = new Dog();
        Class<? extends Dog> aClass = dog.getClass();
        System.out.println("aClass = " + aClass);

        Cat cat = new Cat();
        Class<? extends Cat> aClass1 = cat.getClass();
        System.out.println("aClass1 = " + aClass1);

    }

}

6: Reflection get information

Attribute object       Field         . Set (object, value)

Method object       Method     . Invoke (object) (parameterless method)

                        perhaps       . Invoke (object, parameter value) (parametric method, deformable parameter)

6.1: get class information (father, implemented interface, permission modifier, package name)

@Test
    public void test02() throws ClassNotFoundException {
        Class<?> aClass = Class.forName("com.atguigu.reflect.some.Cat");
        //Get permission modifier
        int modifiers = aClass.getModifiers();
        System.out.println("modifiers = " + modifiers);
        String string = Modifier.toString(modifiers);
        System.out.println("string = " + string);
    }

    @Test
    public void test01(){
        Class<Cat> catClass = Cat.class;
        //Get package name
        Package aPackage = catClass.getPackage();
        System.out.println("aPackage = " + aPackage);
        //Get parent class
        Class<? super Cat> superclass = catClass.getSuperclass();
        System.out.println("superclass = " + superclass);
        //Get implementation interface
        Class<?>[] interfaces = catClass.getInterfaces();
        for (Class<?> in : interfaces) {
            System.out.println("in = " + in);
        }


    }

be careful:

The obtained permission modifiers have corresponding numbers, and Modifier.toString(modifiers) is required;

Underlying implementation:

public static String toString(int mod) {
        StringBuilder sb = new StringBuilder();
        int len;

        if ((mod & PUBLIC) != 0)        sb.append("public ");
        if ((mod & PROTECTED) != 0)     sb.append("protected ");
        if ((mod & PRIVATE) != 0)       sb.append("private ");

        /* Canonical order */
        if ((mod & ABSTRACT) != 0)      sb.append("abstract ");
        if ((mod & STATIC) != 0)        sb.append("static ");
        if ((mod & FINAL) != 0)         sb.append("final ");
        if ((mod & TRANSIENT) != 0)     sb.append("transient ");
        if ((mod & VOLATILE) != 0)      sb.append("volatile ");
        if ((mod & SYNCHRONIZED) != 0)  sb.append("synchronized ");
        if ((mod & NATIVE) != 0)        sb.append("native ");
        if ((mod & STRICT) != 0)        sb.append("strictfp ");
        if ((mod & INTERFACE) != 0)     sb.append("interface ");

        if ((len = sb.length()) > 0)    /* trim trailing space */
            return sb.toString().substring(0, len-1);
        return "";
    }

6.2: create reflection objects

public class Dog {
    @Override
    public String toString() {
        return "Dog{ puppy... }";
    }
}

class Cat {
    @Override
    public String toString() {
        return "Cat{z kitten}";
    }
}


class Test{
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        Scanner in = new Scanner(System.in);

        System.out.println("Enter the object you want to create");

        String objMess = in.next();

        Class<?> aClass = Class.forName("com.atguigu.reflect.start."+objMess);

        Object o = aClass.newInstance();

        System.out.println("---->"+o);

    }

}

6.3.1: get constructor (public private)

Get all public modifier constructors
Constructor<?>[] constructors = aClass.getConstructors();

Get all constructors of this class   Contains non-public
Constructor<?>[] declaredConstructors = aClass.getDeclaredConstructors();

Person person = personClass.newInstance(); The parameterless constructor is called by default
 @Test
    public void test02() throws NoSuchMethodException {
        //1. Get Class
        Person person = new Person();
        Class<? extends Person> aClass = person.getClass();
        //2. Get all public modified constructors
        Constructor<?>[] constructors = aClass.getConstructors();
        for (Constructor<?> constructor : constructors) {
            System.out.println(constructor);
        }
        System.out.println("--------------------declaredConstructors--------------------");
        //Get all constructors of this class that contain non-public
        Constructor<?>[] declaredConstructors = aClass.getDeclaredConstructors();

        for (Constructor<?> d : declaredConstructors) {
            System.out.println("d = " + d);
        }
    }

    @Test
    public void test01() throws IllegalAccessException, InstantiationException {

        //1. Get runtime type
        Class aClass = Person.class;

        //Creating objects with a parameterless constructor
        Object o = aClass.newInstance();
        System.out.println("o = " + o);

    }

6.3.2: get the specified constructor

getDeclaredConstructor(String.class, int.class)

The parameter is a deformable parameter and can be passed in multiple. The data type is Class

Gets the specified constructor based on the formal parameter list passed in

 @Test
    public void test02() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        Class<Person> personClass = Person.class;
        Constructor<Person> constructor = personClass.getDeclaredConstructor(String.class, int.class);
        Person libai = constructor.newInstance("Li Bai", 20);
        System.out.println("libai = " + libai);


    }
    @Test
    public void test01() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
     //1: Gets the class of the runtime
        Class<Person> personClass = Person.class;
        Constructor<Person> declaredConstructor = personClass.getDeclaredConstructor(String.class);

        Person libai  = declaredConstructor.newInstance("Li Bai");
        System.out.println("libai = " + libai);


    }

6.4: get all attributes and operations by reflection:

personClass.getFields()   Get all public properties of this class and its parent class

personClass.getDeclaredFields()   Get all properties in this class (excluding those in the parent class), including non-public

  General fixing steps:

        1> You must first obtain the instance object of the class;

        2> Operation public property:

                2.1: getField("name") gets the name of the attribute and returns it to generate a Field attribute object

                2.2: Field attribute object. Set (object, value);

        3> Operation private properties:

              3.1:      getField("name") gets the name of the property and returns it to generate a Field property object

              3.2:     Field property object. setAccessible(true);

              3.3:     Field property object. Set (object, value);

        4> Operation private static attribute: (static attribute belongs to class and does not need object)

              4.1:     getField("name") gets the name of the property and returns it to generate a Field property object

            4.2:   Field property object. setAccessible(true);

            4.3:   Field property object. set(null, value);

            4.4: acquisition of static attributes      Field property object. get(null)

                

 @Test
    public void test03() throws IllegalAccessException, InstantiationException, NoSuchFieldException {
        //Operation static properties
        //Operation private static properties
        //Because static properties belong to class operations, objects are not required
        Class<Person> personClass = Person.class;
        //Get the instance object of a class first
        //Person person = personClass.newInstance();
        //Get property object
        Field num = personClass.getDeclaredField("num");
        num.setAccessible(true);
        num.set(null,1000);
        //Get property value property object. get()
        Object o = num.get(null);
        System.out.println("o = " + o);
        System.out.println("person = " + person);

    }

    @Test
    public void test02() throws IllegalAccessException, InstantiationException, NoSuchFieldException {
        //Operation private properties
        Class<Person> personClass = Person.class;
        //Get the instance object of a class first
        Person person = personClass.newInstance();
        //At this time, the name attribute object is obtained
        Field salary = personClass.getDeclaredField("salary");
        salary.setAccessible(true);
        salary.set(person,1230.09);
        System.out.println("person = " + person);
    }

    //Action public property
    @Test
    public void test01() throws NoSuchFieldException, IllegalAccessException, InstantiationException {

        Class<Person> personClass = Person.class;
        //Get the instance object of a class first
        Person person = personClass.newInstance();
        //At this time, the name attribute object is obtained
        Field name = personClass.getField("name");
        //set the attribute value of the object person in the way of the attribute object. set
        name.set(person,"libai");
        System.out.println("person = " + person);

    }

6.5: get all methods in this class

public class Person extends Object {


    public void show() {
        System.out.println("this is show()");
    }

    public void show(int a, double b) {
        System.out.println("this is show(int a,double b) " + a + "---> " + b);
    }

    private String show(String str) {
        System.out.println("this is show(String) ---> " + str);
        return str + "666";
    }

    private static int sum(int a, int b) {
        {

            System.out.println("Static methods execute.....");
            return a + b;
        }


    }
}
public class MethodTest {
    @Test
    public void test01(){
        //Get all methods in this class
        Class<Person> personClass = Person.class;
        Method[] declaredMethods = personClass.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            System.out.println("declaredMethod = " + declaredMethod);
        }
    }
    @Test
    public void test02(){
        //Get all public methods of this class and its parent class
        Class<Person> personClass = Person.class;
        Method[] methods = personClass.getMethods();
        for (Method method : methods) System.out.println("method = " + method);
    }
    @Test
    public void test03() throws NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {
        //Operation public parameterless method
        Class<Person> personClass = Person.class;
        //The getMethod() Method returns a Method object
        Method show = personClass.getMethod("show");
        //create object
        Person person = personClass.newInstance();
        //Create object before operation
        Object invoke = show.invoke(person);

    }
    @Test
    public void test04() throws NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {
        //Operation public parameterized method
        Class<Person> personClass = Person.class;
        //create object
        Person person = personClass.newInstance();
        //The getMethod() Method returns a Method object
        Method show = personClass.getMethod("show", int.class, double.class);
        show.invoke(person,100,203.333);
    }
    @Test
    public void test05() throws NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {
        //Operation private parameterized method
        Class<Person> personClass = Person.class;
        //create object
        Person person = personClass.newInstance();
        //The getMethod() Method returns a Method object
        Method show = personClass.getDeclaredMethod("show", String.class);
        show.setAccessible(true);
        Object libai = show.invoke(person, "Li Bai");
        System.out.println("libai = " + libai);


    }
    @Test
    public void test06() throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        //Operation private static parameterized method
        Class<Person> personClass = Person.class;
        //create object
//        Person person = personClass.newInstance();
        //Get method object
        Method sum = personClass.getDeclaredMethod("sum", int.class, int.class);
        sum.setAccessible(true);
        //Static methods do not require objects
        Object invoke = sum.invoke(null, 10, 20);

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


    }
}

6.6: use reflection to break through the limitations of generics

public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        ArrayList<String> list = new ArrayList<>();

        list.add("Li Bai");
        //Add 100 to the collection using reflection
        //Get list runtime class
        Class<? extends ArrayList> aClass = list.getClass();
        //Call the add method of the list
        Method add = aClass.getMethod("add", Object.class);
        Object invoke = add.invoke(list, 100);
        System.out.println("invoke = " + invoke);
        System.out.println(list);

    }

6.7: reflection operation internal class:

public class TestInner {

    @Test
    public void test04() {
        //Gets the runtime class object of the inner class A of the Person class
        Class<Person.A> aClass = Person.A.class;
        //Gets the runtime type of the external class
        Class<?> declaringClass = aClass.getDeclaringClass();
        System.out.println("declaringClass = " + declaringClass);

    }
    @Test
    public void test03() {

        Class<Person> aClass = Person.class;
        //public Class<?>  Getdeclarangclass(): if the class object represents
        // If the class or interface of is an internal class or internal interface, its external class or external interface is returned; otherwise, null is returned.
        Class<?> declaringClass = aClass.getDeclaringClass();
        System.out.println("declaringClass = " + declaringClass);

    }


    @Test
    public void test02(){
        Class<Person> aClass = Person.class;
        //Get all inner classes of this class
        Class<?>[] declaredClasses = aClass.getDeclaredClasses();
        for (Class<?> declaredClass : declaredClasses) {
            System.out.println("declaredClass = " + declaredClass);
        }


    }
    @Test
    public void test01(){
        Class<Person> personClass = Person.class;
        //Gets this class and the public inner class inherited from the parent class
        Class<?>[] classes = personClass.getClasses();
        for (Class<?> aClass : classes) {
            System.out.println("aClass = " + aClass);
        }


    }
}

6.8: reflection operation array:

An Array class is also provided under the java.lang.reflect package. The Array object can represent all arrays.

The Array class provides the following methods:

Public static object newinstance (class <? > componenttype, int... Dimensions): creates a new array with the specified component type and dimension.

public static void setXxx(Object array,int index,xxx value): modify the value of the [index] element in the array to value. Xxx here corresponds to 8 basic data types. If the type of this attribute is a reference data type, the set(Object array,int index, Object value) method is directly used.

public static xxx getXxx(Object array,int index,xxx value): returns the value of the [index] element in the array. Xxx here corresponds to 8 basic data types. If the type of this attribute is a reference data type, you can directly use the get(Object array,int index) method.

@Test
    public void test010(){
        //Is an array of String type with length of 6
        Object instance = Array.newInstance(String.class, 6);
//        instance[0] = "Li Bai";
        //Assign a value to an array
        Array.set(instance,0,"libai");
        Array.set(instance,1,"Du Fu");
        //Get value
        Object o = Array.get(instance, 1);
        System.out.println("o = " + o);


    }

6.8: Reflection reading annotation information:

Meta annotation:
Target: Specifies the location of the annotation
Retention: the lifecycle of an annotation

If you want annotations to be read using reflection, @ Retention(RetentionPolicy.RUNTIME)

@MyAnno("login")
public class Person {
    @MyAnno
    String name;
    @MyAnno
    public void show(){

    }
}



@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD,ElementType.METHOD,ElementType.TYPE})
public @interface MyAnno {
    String value() default "hello";
}


 @Test
    public void test01(){

        Class<Person> personClass = Person.class;
        //Gets the specified annotation
        MyAnno myAnno = personClass.getDeclaredAnnotation(MyAnno.class);
        String value = myAnno.value();
        System.out.println("value = " + value);

    }

Tags: Java Back-end

Posted on Fri, 19 Nov 2021 05:26:07 -0500 by richardwarren