Basic introduction to Java reflection (study notes)

First of all, understand the stages (three stages) that Java code goes through in the computer

Insert picture description here

Reflection : encapsulate the various components of the class as other objects

benefit:

  1. When the program is running, get these objects
  2. Can be decoupled to improve the scalability of the program

Ways to obtain the Class object:

 1. 通过类型获得
  // 语法:类名.class
  // 应用场景:确定类型等
    Class beansClass = 类名.class;
   
 2 通过实例对象获得
    // 语法:变量.getClass()
    // 应用场景:在方法内部通过参数获得类型等 
    // 先给你 new一个对象
    Beans beans = new Beans();
    Class<? extends Beans> aClass = beans.getClass();

 3 通过字符串获得
    // 语法:Class.forName("全限定类名")
    // 应用场景:通过配置获得字符串等
    Class<?> aClass1 = Class.forName("Demo01.Beans");

The same bytecode file (*.Class) will only be loaded once in the program running again. No matter which way to obtain the Class object, it is the same

Class object function:

Get function:

  1. Get member variables

    Field[] getFields()

    Field getField(String name)

    Field[] getDeclaredFields( )

    Field getDeclaredField(String name)

  2. Get construction method

    Constructor<?> getConstructors()

    Constructor<T> getConstructor(类<?>... parameterTypes)

    Constructor<T> getDeclaredConstructor(类<?>... parameterTypes)

    Constructor<?>[] getDeclaredConstructors()

  3. Get member method

    Method getMethods()
    Method getMethod(String name, 类<?>... parameterTypes)

    Method[] getDeclaredMethods()
    Method getDeclaredMethod(String name, 类<?>... parameterTypes)

  4. Get class name

    String getName()

Function demonstration: (Get member variables)

Person class:

public class Person {
    
    
    public int id;
    private String name;
    private int age;

    public Person() {
    
    
    }

    public Person(int id, String name, int age) {
    
    
        this.id = id;
        this.name = name;
        this.age = age;
    }

    public int getId() {
    
    
        return id;
    }
    public void setId(int id) {
    
    
        this.id = id;
    }
    public String getName() {
    
    
        return name;
    }
    public void setName(String name) {
    
    
        this.name = name;
    }
    public int getAge() {
    
    
        return age;
    }
    public void setAge(int age) {
    
    
        this.age = age;
    }
}

Field[] getFields() to get all the member variables

public class FieldDemo01 {
    
    
    public static void main(String[] args) throws Exception {
    
    
        //通过字符串的方式获取
        Class<?> aClass = Class.forName("Demo02.Person");
        //获取所有的成员变量
        Field[] fields = aClass.getFields();
        for (Field field : fields) {
    
    
            System.out.println(field);
        }
    }
}

Insert picture description here

However, why there are three member variables in my Person class that can loop only one

Looking back at our Person class

Insert picture description here

In addition to other members of the ID variables are Private modified that now we know Field[] getFields()to get all public member variables modified

Therefore, the term Field getField(String name)can analyze String nameGets the name of the member variables ( getFields()get modified all public member variables) that Field getField(String name)is to get the name of the specified public member variables modified.

So what can we do to get member variables?

  1. Assignment

    set(Object obj, Object value) Set the field represented by this Field object on the specified object parameter to the specified new value.

  2. Get value

    get(Object obj) Returns the value of the field represented by Field, on the specified object.

  3. setAccessible(true)

    Ignore the security check of the access permission modifier (we can all use it in the following functions)

Code demo: (format)

public class FieldDemo01 {
    
    
    public static void main(String[] args) throws Exception {
    
    
        //通过字符串的方式获取
        Class<?> aClass = Class.forName("Demo02.Person");
        //获取指定名字的public修饰的成员变量
        Field id = aClass.getField("id");
        //设置成员变量id的值
        Person person = new Person();
        id.set(person,8848);
        //获取成员变量id的值
        Object o = id.get(person);
        System.out.println("id是"+o);
    }
}

Insert picture description here

We have learned the above two functions so the following two functions are even simpler:

Field[] getDeclaredFields( ) Get all member variables (regardless of modifiers)

public class FieldgetConstructorDemo01 {
    
    
    public static void main(String[] args) throws Exception {
    
    
        //通过字符串的方式获取
        Class<?> aClass = Class.forName("Demo02.Person");
        //不考虑 修饰符
        Field[] declaredFields = aClass.getDeclaredFields();
        for (Field declaredField : declaredFields) {
    
    
            System.out.println(declaredField);
        }
    }
}

Insert picture description here

Then is Field getDeclaredField(String name)not the member variable with the specified name

Then let's take a look at his assignment value

public class FieldgetConstructorDemo01 {
    
    
    public static void main(String[] args) throws Exception {
    
    
        //通过字符串的方式获取
        Class<?> aClass = Class.forName("Demo02.Person");
        //根据变量名称获取
        Field name = aClass.getDeclaredField("name");
        Person person = new Person();
        //忽略访问权限修饰符的安全检查 (暴力反射 FBI! open the door)
        name.setAccessible(true);
        //赋值
        name.set(person,"Jo级生物");
        //获取
        Object o = name.get(person);
        System.out.println("我是 :"+o);

    }
}

If there is no setAccessible (true), the private cannot be accessed, so an illegal access exception will be reported

Insert picture description here

Function demonstration: (Get construction method)

public class Demo01 {
    
    
    public static void main(String[] args) throws Exception {
    
    
        Class<?> aClass = Class.forName("ConstructorDemo03.Person");
        //构造方法 类名和方法名是相同的
        //区分 : 参数不一样 而这里要求的参数类型是不同参数的Class对象
        Constructor<?> constructor = aClass.getConstructor(int.class,
                String.class,
                int.class);
        System.out.println(constructor);
    }
}

Insert picture description here

Constructor:构造方法
    创建对象:T  newInstance(Object... initargs)

usage:

        Constructor<?> constructor = aClass.getConstructor(int.class,
                String.class,
                int.class);
        //创建对象
        Object o = constructor.newInstance(1, "张三", 20);
        System.out.println(o);

Insert picture description here

It's easy to create an empty parameter:

Insert picture description here

Definition is a form of variable parameters

 Constructor<?> constructor = aClass.getConstructor();
        //创建对象
        Object o = constructor.newInstance();
        System.out.println(o);

You can also use newInstancethe methods in the Class object

Class<?> aClass = Class.forName("ConstructorDemo03.Person");
Object o1 = aClass.newInstance();
System.out.println(o1);

If our construction method is private

Then you can use Constructor<T> getDeclaredConstructor(类<?>... parameterTypes)

In fact, the usage is basically the same as the above (get member variables):

public class Demo02 {
    
    
    public static void main(String[] args) throws Exception {
    
    
        Class<?> aClass = Class.forName("ConstructorDemo03.Person");
        //暴力反射
        Constructor<?> dct = aClass.getDeclaredConstructor(int.class,
                String.class,
               int.class);
        dct.setAccessible(true);
        Object o = dct.newInstance(1, "张三", 20);
        System.out.println(o);
    }
}

Function demonstration: (Get member method)

Three methods have been added to Person:

public class Person {
    
    
    public int id;
    private String name;
    private int age;

    public Person() {
    
    
    }

    public Person(int id, String name, int age) {
    
    
        this.id = id;
        this.name = name;
        this.age = age;
    }

    public int getId() {
    
    
        return id;
    }
    public void setId(int id) {
    
    
        this.id = id;
    }
    public String getName() {
    
    
        return name;
    }
    public void setName(String name) {
    
    
        this.name = name;
    }
    public int getAge() {
    
    
        return age;
    }
    public void setAge(int age) {
    
    
        this.age = age;
    }

    @Override
    public String toString() {
    
    
        return "Person{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    public void eat(){
    
    
        System.out.println("我在喝刘一碗羊汤");
    }
    public void eat(int count){
    
    
        System.out.println("我在刘一碗喝了"+count+"碗羊汤");
    }
    private void swim(){
    
    
        System.out.println("我在游泳");
    }
}
public class Demo01 {
    /*
    *  执行方法
    * */
    public static void main(String[] args) throws Exception {
        Class<?> aClass = Class.forName("MethodDemo04.Person");
        //获得指定名称的方法
        Method method = aClass.getMethod("eat");
        Person person = new Person();
        //执行方法
        method.invoke(person);
        //如果方法中传入了参数
        Method method1 = aClass.getMethod("eat",int.class);
        Person person1 = new Person();
        method1.invoke(person1,60);

        //获取所有的public修饰的方法
         Method[] methods = aClass.getMethods();
         for (Method method2 : methods) {
             System.out.println(method2);
         }
        
        //拿到私有的方法
        Method swim = aClass.getDeclaredMethod("swim");
        Person person2 = new Person();
        swim.setAccessible(true);
        swim.invoke(person2);
    }
}

Because there are many methods to get all public modification, so he did not let him execute

Insert picture description here

Guess you like

Origin blog.csdn.net/agood_man/article/details/108476615