Summary of Java reflection technology

Posted by woobarb on Wed, 19 Jan 2022 12:19:25 +0100

Reflection is the ability to dynamically obtain the properties and methods of classes and dynamically manipulate the properties and methods of objects during program operation.

In fact, reflection technology is widely used, especially various framework technologies are inseparable from reflection. Some commonly used jar package middleware (such as JDBC access drivers provided by various database manufacturers) also use reflection technology. The reason to summarize reflection technology is mainly to understand the relevant Java framework related source code, understand the cleverness of its design ideas, and better learn and master various frameworks.


First, we prepare a Person class. All the following code demonstrations use this class. The code is as follows:

package com.jobs.reflect;

public class Person {
    //Public field
    public String name;
    public int age;
    //Private field
    private int salary;

    //------------------------------

    //non-parameter constructor 
    public Person() { }

    //All parameter constructor
    public Person(String name, int age, int salary) {
        this.name = name;
        this.age = age;
        this.salary = salary;
    }

    //private constructors 
    private Person(String name, int age) {
        this.name = name;
        this.age = age;
        this.salary = 100;
        System.out.println("Private constructor called...");
    }

    //------------------------------

    //Private method
    private void method1() {
        System.out.println("Private method method1 Called, no parameter, no return value");
    }

    public String method2(String name) {
        System.out.println("method2 Called, with parameters and return values. The parameters are" + name);
        return "method2 The return value is:" + name + " fastoder...";
    }
}

1, Three ways to get the Class object of a Class

Why get the Class object of a Class?

The Class object of a Class can be understood as a template.
After obtaining the Class object of a Class, it is equivalent to obtaining the template of a Class, and then you can perform the following operations:

  • Get any properties and methods in the Class object (template). Even private properties and methods can be obtained.
  • Create an object instance through a Class object (template). By referring to the attributes and methods in the template, you can assign values to the attributes of the instance object and call its methods

There are three ways to get the Class template object of a Class:

  • Get from the file and call class Forname (full class name) method
  • Get in memory, you can call the Class attribute of a Class
  • For an instantiated object, you can call its getClass() method

No matter which method is used to obtain, the obtained object is the same object. The code is demonstrated as follows:

public class reflectDemo1 {

    public static void main(String[] args) throws ClassNotFoundException {

        //The first method is to obtain the Class object of Person
        Class cla1 = Class.forName("com.jobs.reflect.Person");
        System.out.println(cla1);

        //The second method is to obtain the Class object of Person
        Class cla2 = Person.class;
        System.out.println(cla2);

        //The third way is to obtain the Class object of Person
        Person per = new Person();
        Class cla3 = per.getClass();
        System.out.println(cla3);

        //Either way, the same class object of Person is obtained
        System.out.println(cla1 == cla2);  //true
        System.out.println(cla1 == cla3);  //true
    }
}

2, Get constructor and create instance

Through the getConstructors method, you can get all the construction methods of public decoration

Through the getdeclaraedconstructors method, you can obtain all construction methods, including those modified by private

Through getconstructor (parameter type...) Method, you can get a specific constructor of the public modifier

Through getdeclaraedconstructor (parameter type...) Method, you can obtain a specific construction method, including private construction methods

By constructing the newinstance of the method object (parameter value...) Method to create an object instance.

Note: if you want to create an instance object using a private constructor object, you need to call the setAccessible(boolean flag) method of the private constructor object and pass in true. (true means to cancel the security access restriction)

The specific demonstration code is as follows:

public class reflectDemo2 {
    public static void main(String[] args) {

        try {
            //Gets the Class object of Person
            Class cla = Class.forName("com.jobs.reflect.Person");

            System.out.println("Person All construction methods of class are:");
            //Get all construction methods, including private construction methods
            Constructor[] constructors = cla.getDeclaredConstructors();
            for (Constructor constructor : constructors) {
                System.out.println(constructor);
            }

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

            //Get the parameterless construction method and create an instance object
            Constructor constructor1 = cla.getConstructor();
            Person per1 = (Person) constructor1.newInstance();
            System.out.println(per1); //Print the address value of the instantiated object

            //Get the full parameter construction method and create an instance object
            Constructor constructor2 = cla.getConstructor(String.class, int.class, int.class);
            Person per2 = (Person) constructor2.newInstance("Hou Pangpang", 40, 22000);
            System.out.println(per2); //Print the address value of the instantiated object

            //Get the private constructor and create an instance object
            Constructor constructor3 = cla.getDeclaredConstructor(String.class, int.class);
            //Remove security access restrictions
            constructor3.setAccessible(true);
            Person per3 = (Person) constructor3.newInstance("Ren Feifei", 38);
            System.out.println(per3); //Print the address value of the instantiated object

        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}

/* 
The printed results are as follows:
Person All construction methods of class are:
private com.jobs.reflect.Person(java.lang.String,int)
public com.jobs.reflect.Person(java.lang.String,int,int)
public com.jobs.reflect.Person()
--------------------------
com.jobs.reflect.Person@12edcd21
com.jobs.reflect.Person@34c45dca
 Private constructor called
com.jobs.reflect.Person@52cc8049
*/

3, Get field and assign value

All public modified fields can be obtained through the getFields() method

Through the getdeclaraedfields () method, you can get all fields, including private fields

Through the getField(String name) method, you can get a specific field decorated by public

Through the getdeclaraedfield (string name) method, you can obtain a specific field, including private fields

Assign a value to the field through the set(Object obj, Object value) method. The first parameter is the specific instantiated object

Get the value of a specific field through the get(Object obj) method. This parameter is a specific instantiated object

Note: if you want to get the value of the private field and set the value of the private field, you need to call the setAccessible(boolean flag) method of the private field object and pass in true. (true means to cancel the security access restriction)

The specific demonstration code is as follows:

public class reflectDemo3 {
    public static void main(String[] args) {

        try {
            //Gets the Class object of Person
            Class cla = Class.forName("com.jobs.reflect.Person");

            System.out.println("Person All fields of the class are:");
            Field[] fields = cla.getDeclaredFields();
            for (Field field : fields) {
                System.out.println(field);
            }

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

            //Get the parameterless construction method and create an instance object
            Constructor cst = cla.getConstructor();
            Person per = (Person) cst.newInstance();

            //Assign a value to name
            Field fieldName = cla.getField("name");
            fieldName.set(per, "Qiao Doudou");

            //Assign value to age
            Field fieldAge = cla.getField("age");
            fieldAge.set(per, 38);

            //Copy to private field salary
            Field fieldSalary = cla.getDeclaredField("salary");
            //Remove security access restrictions
            fieldSalary.setAccessible(true);
            fieldSalary.set(per, 28000);

            //Get the value of the corresponding field
            System.out.println("Person The field values of the instantiated object are:");
            System.out.println(fieldName.getName() + " ---> " + fieldName.get(per));
            System.out.println(fieldAge.getName() + " ---> " + fieldAge.get(per));
            System.out.println(fieldSalary.getName() + " ---> " + fieldSalary.get(per));

        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}

/*
The printed results are as follows:
Person All fields of the class are:
public java.lang.String com.jobs.reflect.Person.name
public int com.jobs.reflect.Person.age
private int com.jobs.reflect.Person.salary
--------------------------
Person The field values of the instantiated object are:
name ---> Qiao Doudou
age ---> 38
salary ---> 28000
*/

4, Get method and call method

Through the getMethods() method, you can get all public modified methods, including inherited methods

Through the getdeclaraedmethods () method, you can get all the methods, but not the inherited methods

Through getmethod (method name, parameter type...) Method, you can get a specific public modified method

Through getdeclaraedmethod (method name, parameter type...) Method, you can get a specific method, including private methods

Via invoke(Object obj, parameter value...) Method, you can call a specific method, and the first parameter is a specific instantiated object

Note: if you want to call a private method, you need to call the setAccessible(boolean flag) method of the private method object and pass in true. (true means to cancel the security access restriction)

The specific demonstration code is as follows:

public class reflectDemo4 {
    public static void main(String[] args) {

        try {
            //Gets the Class object of Person
            Class cla = Class.forName("com.jobs.reflect.Person");

            System.out.println("Person All methods of class are:");
            Method[] methods = cla.getDeclaredMethods();
            for (Method method : methods) {
                System.out.println(method);
            }

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

            //Get the parameterless construction method and create an instance object
            Constructor cst = cla.getConstructor();
            Person per = (Person) cst.newInstance();

            //Call private method, private method has no parameters
            Method method1 = cla.getDeclaredMethod("method1");
            //Remove security access restrictions on private methods
            method1.setAccessible(true);
            method1.invoke(per);

            //Call a common method with parameters and return values
            Method method2 = cla.getMethod("method2", String.class);
            String result = (String) method2.invoke(per, "Ren Tianpeng");
            System.out.println(result);

        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}

/*
The printed results are as follows:
Person All methods of class are:
public java.lang.String com.jobs.reflect.Person.method2(java.lang.String)
private void com.jobs.reflect.Person.method1()
--------------------------
Private method method1 is called with no parameters and no return value
method2 Called, with parameters and return values. The parameter is Ren Tianpeng
method2 The return value is: Ren Tianpeng fastoder
*/

So far, some simple reflection technologies about Java have been introduced. The above codes have been tested and are correct. I hope they can be helpful to you.