Java反射机制快速上手

反射机制

Java的反射(reflection)机制是指在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类的成员变量和方法,可以调用任意一个对象的属性和方法。这种动态获取程序信息以及动态调用对象的功能称为Java语言的反射机制。

下面是我们用于测试反射机制的Person类:

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

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();
        }
    }
}

猜你喜欢

转载自blog.csdn.net/qq_42078712/article/details/131055119