Fundamentals of java reflection mechanism

Reflection overview

Reflection is that for any Class, you can directly get all the components of this Class "at run time".

At runtime, you can directly get the Constructor object of this class: Constructor
At runtime, you can directly get the member variable object of this class: Field
At runtime, you can directly get the member Method object of this class: Method
This ability of dynamically obtaining class information and dynamically calling components in classes at runtime is called the reflection mechanism of Java language.

The key of reflection mechanism: the first step of reflection is to get the compiled Class object first, and then you can get all the components of Class.

HelloWorld.java -> javac -> HelloWorld.class
Class c = HelloWorld.class;

In essence, it is Class file is a class object.

The basic function of reflection: get the bytecode file object of the class at run time, and then parse all the components in the class.
The core idea and key of reflection is to get the compiled class file object.

class structure in memory

Reflection get class object

The first step of reflection is to get the object of Class


Method 1: Class C1 = class Forname ("full class name");
Method 2: Class c2 = class name class
Method 3: Class c3 = object getClass();

    @Test
    public void test1() {

        Student student1 = new Student();

        Student student2 = new Student();


//        The first method is to get class objects
        Class<?> s1 = null;

        try {
            s1 = Class.forName("Student");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

//        The second method is to obtain class objects
        Class<Student> s2 = Student.class;

//        The third method is to obtain class objects
        Class<? extends Student> s3 = student1.getClass();

        System.out.println(s1);
        System.out.println(s2);
        System.out.println(s3);

    }

Reflection get constructor object

Get the constructor object using reflection technology and use

API

    @Test
    public void test2() throws NoSuchMethodException {

        Class<Student> sc = Student.class;

//        1. Get all the constructors
        Constructor<?>[] constructors = sc.getDeclaredConstructors();

//        Name of output constructor + number of parameters
        for (Constructor<?> constructor : constructors) {
            System.out.println(constructor.getName() + " Number of parameters:" + constructor.getParameterCount() + "individual");
        }

//        2. Get a single constructor
        Constructor<Student> constructor = sc.getDeclaredConstructor(String.class, String.class);

        System.out.println(constructor.getName() + "Number of parameters:" + constructor.getParameterCount());

    }

Obtain the constructor object using reflection technology and create an object using the obtained content

The function of the constructor after reflection is still to create an object. If the constructor is public, you can directly create a new object. If the constructor is private, you need to violently reflect the constructor in advance and then construct the object.

Reflection can directly replace encapsulation, and private reflection can also be executed.

//        3. Create an object using a parameterless constructor
        Student o = (Student)constructors[0].newInstance();
        System.out.println(o);

//        4. Create objects using full parameter constructors

        constructor.setAccessible(true);  // Violent reflex

        Student student = constructor.newInstance("Sun WuKong", "20");

        System.out.println(student.getName() + student.getAge());

Get member variable object by reflection



The parameter is a variable name

During the assignment operation, you need to select which object is first, and then give it the value to be assigned. When obtaining the value, you need to find the value of which object to obtain first.

//        Assign a value to the member variable name
        Student student = new Student();  // First, we need to new out an object, so that the paper can know which member variable of which object is assigned a value

        field.setAccessible(true);

        field.set(student,"Qi Tian Da Sheng");

        System.out.println(student.getName());

        String name= (String) field.get(student);

        System.out.println(name);

Here you can also use the way of violent reflection.

Reflection get method object



@Test
    public  void test5() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {

        Class<Student> sc = Student.class;

        Method[] methods = sc.getDeclaredMethods();

        for (Method method : methods) {
            String name = method.getName();
            System.out.println(name);
        }

        Method eat = sc.getDeclaredMethod("eat", String.class);

        Student student = new Student();

        Object invoke = eat.invoke(student, "puppy");

        System.out.println(invoke);

        Method eat1 = sc.getDeclaredMethod("eat", String.class,String.class);

        Object invoke1 = eat1.invoke(student, "puppy", "Eat delicious food");

        System.out.println(invoke1);

    }

Bypassing the compilation phase to add data to the collection

Reflection is a technology that works at runtime. At this time, the generics of the collection will not produce constraints. At this time, other elements of any type can be stored for the collection
Generics can only restrict the collection to operate certain data types in the compilation stage. When compiling into a Class file and entering the running stage, its real type is ArrayList, and generics are equivalent to being erased.
You can get the class class through the object, find the add method, and then call the add method.

@Test
    public void test6() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {

        ArrayList<String> list = new ArrayList<>();

        list.add("lala");

        System.out.println(list);

        Class aClass = list.getClass();

        Method add = aClass.getDeclaredMethod("add", Object.class);

        add.invoke(list,1);

        System.out.println(list);

    }

Reflection as a general framework

Requirement: for any object, if you don't know the object field, you can store the field name and corresponding value of the object in the file.
Define a method that can receive objects of any class.
Every time you receive an object, you need to resolve the names of all member variables of the object.
This object may be arbitrary, so how can we know the names of all member variables of this object?
Use reflection to get the Class object of the object, and then get all member variable information.
Traverse the member variable information, and then extract the specific value of the member variable in the object
Save the member variable name and value into the file.

Keywords: Java Back-end Framework reflection

Added by BornForCode on Sat, 05 Feb 2022 10:19:28 +0200