Quick start of Java reflection mechanism

reflection mechanism

The reflection mechanism of Java means that in the running state of the program, objects of any class can be constructed, the class to which any object belongs, the member variables and methods of any class can be known, and the method of any object can be called. properties and methods. This function of dynamically obtaining program information and dynamically calling objects is called the reflection mechanism of the Java language.

Here is the Person class we used to test the reflection mechanism:

package entity;

public class Person {
    
    

    private String name;
    protected int age;
    public String sex;

    public Person() {
    
    }

    private Person(int age) {
    
    
        this.age = age;
    }

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

    public void setName(String name) {
    
    
        this.name = name;
    }

    public void setAge(int age) {
    
    
        this.age = age;
    }

    public void setSex(String sex) {
    
    
        this.sex = sex;
    }

    public String getName() {
    
    
        return name;
    }

    public int getAge() {
    
    
        return age;
    }

    private void testPrivateMethod() {
    
    
        System.out.println("testPrivateMethod被调用");
    }
}

demo for testing the reflection mechanism

import entity.Person;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class ReflectionDemo {
    
    

    public static void main(String[] args) throws Exception{
    
    
//        getReflectionClass();
//        getRelectionConstructors();
//        getRelectionInstantiating();
//        getRelectionFields();
        getRelectionMethods();
    }

    public static void getReflectionClass() throws Exception {
    
    
        /*---------------------
        三种反射获得class实例的方法
        ---------------------*/
        // 通过类的class获得Class实例
        Class<Person> personClass = Person.class;
        // 通过类的包名获得Class实例
        Class<Person> personClass1 = (Class<Person>)Class.forName("entity.Person");
        // 通过对象获得Class实例
        Person person = new Person("x", 1);
        Class<Person> personClass2 = (Class<Person>)person.getClass();

        System.out.println("personClass = " + personClass);
        System.out.println("personClass1 = " + personClass1);
        System.out.println("personClass2 = " + personClass2);
    }

    public static void getRelectionConstructors() throws Exception {
    
    
        /*---------------------
        获取class中构造方法:
            Constructor[] getDeclaredConstructors() 用于获取当前类中所有构造方法,不包括包括父类中的构造方法。
            Constructor[] getConstructors()  用于获取本类中所有public修饰的构造方法,不包括父类的构造方法。

        获取class中指定构造方法:
            Constructor getDeclaredConstructor(Class<?>... parameterTypes)  该方法用来获取类中任意的构造方法,包括private修饰的构造方法。无法通过该方法获取到父类的构造方法。
            Constructor getConstructor(Class<?>... parameterTypes)  该方法只能用来获取该类中public的构造方法。无法获取父类中的构造方法。
        ---------------------*/
        Class<Person> personClass = Person.class;

        /* getDeclaredConstructors() 获取所有类型 */
        Constructor[] declaredConstructors1= personClass.getDeclaredConstructors();
        System.out.println("declaredConstructor1:");
        for(Constructor declaredConstructor:declaredConstructors1) {
    
    
            System.out.println(declaredConstructor);
        }
        System.out.println("---------------------");

        /* getConstructors() 只获取public修饰 */
        Constructor[] declaredConstructors2= personClass.getConstructors();
        System.out.println("declaredConstructor2:");
        for(Constructor declaredConstructor:declaredConstructors2) {
    
    
            System.out.println(declaredConstructor);
        }
        System.out.println("---------------------");

        try {
    
    
            // 按照参数配置来查找构造器
            Constructor<Person> declaredConstructor = personClass.getDeclaredConstructor();
            Constructor<Person> declaredConstructor2 = personClass.getDeclaredConstructor(String.class,int.class);
            System.out.println("declaredConstructor = " + declaredConstructor);
            System.out.println("declaredConstructor2 = " + declaredConstructor2);
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
    }

    public static void getRelectionInstantiating() throws Exception {
    
    
        /* ---------------------
        通过Class的newInstance实例化对象,直接调用newInstance方法即可完成对象的实例化
        使用Constructor实例化对象
        --------------------- */
        Class<Person> personClass = Person.class;

        // newInstance只能实例化无参构造方法的类,同时这个无参构造方法不能使用private修饰。
        // 否则会抛出异常。推荐使用Constructor来实例化对象
        try {
    
    
            Person person = personClass.newInstance();
            System.out.println("person = " + person);
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }

        // Constructor实例化对象
        try {
    
    
            Constructor<Person> declaredConstructor = personClass.getDeclaredConstructor(String.class, int.class);
            // 通过Constructor实例化私有的构造方法时,需要通过Constructor的setAccessible(true)
            // 来使Constructor可见(相当于临时将private变成public)
            declaredConstructor.setAccessible(true);
            Person x = declaredConstructor.newInstance("x", 1);
            System.out.println(x.getName() + "---" + x.getAge());
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
    }

    public static void getRelectionFields() throws Exception {
    
    
        /* ---------------------
        获取类的成员变量:
        getDeclaredFields() 获取该类中所有成员变量,无法获取到从父类中继承的成员变量。
        getFields() 获取类中所有public的成员变量,包括从父类中继承的public的成员变量。
        --------------------- */
        Class<Person> personClass = Person.class;

        // 通过getDeclaredFields()来获取Person的成员变量,无论是用private修饰还是用public修饰
        Field[] declaredFields = personClass.getDeclaredFields();
        for (Field field : declaredFields) {
    
    
            System.out.println(field.toString());
        }

        // getFields方法只获取Person类中public的成员变量
        Field[] fields = personClass.getFields();
        for (Field field : fields) {
    
    
            System.out.println(field.toString());
        }

        // 反射获取并修改类的成员变量
        Person person = new Person("x", 1);
        try {
    
    
            System.out.println("反射修改前name为:" + person.getName());
            // 获取Person中的私有成员变量name
            Field name = personClass.getDeclaredField("name");
            // 将name设置为可见
            name.setAccessible(true);
            // 修改person实例中name的值
            name.set(person, "z");
            System.out.println("反射修改后name为:" + person.getName());
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
    }

    public static void getRelectionMethods() throws Exception {
    
    
        /* ---------------------
        获取类的方法:
        getDeclaredMethods() 获取本类中所有方法,不包括从父类中继承的方法。
        getMethods() 获取类中所有public方法,包括从父类中继承的public方法。
        --------------------- */
        Class<Person> personClass = Person.class;

        // getDeclaredMethods() 获取类中的所有方法,包括私有方法,但不包括父类中的方法。
        Method[] declaredMethods = personClass.getDeclaredMethods();
        // 遍历并打印方法信息
        for (Method method :declaredMethods) {
    
    
            System.out.println("getDeclaredMethods:"+method.toString());
        }
        System.out.println("---------------------");

        // getMethods() 获取类中所有public方法,包括从父类中继承的public方法。
        Method[] methods = personClass.getMethods();
        // 遍历methods并打印方法信息
        for (Method method : methods) {
    
    
            System.out.println("getMethods:"+method.toString());
        }
        System.out.println("---------------------");

        // 反射调用对象的私有方法testPrivateMethod
        try {
    
    
            // 获取Person类中的私有方法testPrivateMethod
            Method testPrivateMethod = personClass.getDeclaredMethod("testPrivateMethod");
            // 将testPrivateMethod方法设置为可见
            testPrivateMethod.setAccessible(true);
            // 反射调用testPrivateMethod方法
            Constructor<Person> declaredConstructor = personClass.getDeclaredConstructor(String.class, int.class);
            declaredConstructor.setAccessible(true);
            Person x = declaredConstructor.newInstance("x", 1);
            testPrivateMethod.invoke(x);
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
    }
}

Guess you like

Origin blog.csdn.net/qq_42078712/article/details/131055119