Java实现反射的常见用法完整代码示例

具体文章: Java面试重点_4. 一文彻底搞懂Java中的反射

package cn.cyy.cl.common.bean;

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

public class Dog {
    
    
    //Dog实体类
    int age;
    String name;
    public String field = "我是一个参数, 你获取到我了";
    private String field1 = "我是一个私有参数, 你用什么娶到我的? ";

    //私有的有参构造方法
    private Dog(int age, String name){
    
    
        this.age = age;
        this.name = name;
    }
    //公有的无参构造方法
    public Dog(){
    
    }

    //tostring方法
    public String toString(){
    
    
        return "Dog: "+name+", age: "+age;
    }

    //整点dog类的方法
    public void eat(String food, int kg){
    
    
        System.out.println("dog eat food "+food + " "+kg+"kg");
    }

    //dog私有方法
    private void eatShit(String food){
    
    
        System.out.println("sometimes, dog eat some shit food :"+food);
    }

    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException, NoSuchFieldException {
    
    
        
        //获取Class对象的四种方式
        //1. 通过Class.forName("全类名");
        Class clazz1 = Class.forName("cn.cyy.cl.common.bean.Dog");

        //2. 通过运行时类.class
        Class<Dog> clazz2 = Dog.class;
        System.out.println(clazz2);

        //3. 通过运行时对象.getClass();
        Dog dog = new Dog();
        Class clazz3 = dog.getClass();

        //4. 通过类加载器
        ClassLoader classLoader = Dog.class.getClassLoader();
        Class clazz4 = classLoader.loadClass("cn.cyy.cl.common.bean.Dog");

        System.out.println(clazz1.hashCode());
        System.out.println(clazz2.hashCode());
        System.out.println(clazz3.hashCode());
        System.out.println(clazz4.hashCode());

        /
        clazz2.getSimpleName(); //获取全类名
        clazz2.getPackage().getName(); //获取包名

        /
        //获取被反射类的构造方法
        //获取Dog类的class对象
        Class<Dog> clazz = Dog.class;

        //方法1, 调用Dog类的无参构造方法
        Dog dog1 = clazz.newInstance();

        //1-1, 尝试获取dog类的带参私有构造方法
        //Dog dog2 = (Dog)clazz.newInstance(int.class, String.class); //这种会报错
        Constructor<Dog> constructor = clazz.getConstructor();
        Dog dog3 = constructor.newInstance();

        //方法2, 使用getDeclaredConstructor调用dog 的私有方法, 并传入构造方法需要的反射类
        //构造器对象调用带参构造方法, 并传入相应的实参.
        //无参构造: Dog dog3 = clazz.newConstructor().newInstance();
        //有参构造: Dog dog4 = (clazz.getDeclaredConstructor(int.class, String.class).newInstance(2, "sb"));
        Constructor<Dog> declaredConstructor = clazz.getDeclaredConstructor(int.class, String.class);
        Dog dog2 = declaredConstructor.newInstance(2, "sb");
        System.out.println(dog2);


        ///
        //获取被反射类实例对象的字段( filed.getField(被反射类的实例对象)
        Class<Dog> clazzField = Dog.class;
        Dog dog4 = clazzField.getConstructor().newInstance();

        Field publicField = clazzField.getField("field");

        System.out.println(publicField.get(dog4));

        Field privateField = clazz.getDeclaredField("field1");
        System.out.println(privateField.get(dog4));
        System.out.println("=====================================");

        //获取字段数组(  clazz.getFields())
        Field[] fields = clazzField.getDeclaredFields();

        for (Field field : fields) {
    
    
            System.out.println("字段名称: "+ field.getName() + ",内容: "+field.get(dog4));
        }
        System.out.println("=====================================");

        //通过反射, 修改字段的值 ( 属性.set(对象, 属性的新值))
        privateField.set(dog4, "通过 getDeclaredField, 我们可以获取私有属性(字段)");
        System.out.println(privateField.get(dog4));

        System.out.println(privateField.getName()); //获取字段名, field.getName();


        ///
        //通过反射获取被反射类的各种方法并调用这些方法
        // class对象-->被反射类的对象-->获取要调用的方法(传入参数类类型)-->调用方法(传入具体的参数值)
        Class clazz5 = Class.forName("cn.cyy.cl.common.bean.Dog");

        //获取被反射类的实例
        Dog dog5 = (Dog)clazz5.newInstance();

        //1. 获取公有的eat方法, 并调用,  class类对象.getMethod("方法", 参数列表的数据类型的类对象);
        Method eat = clazz5.getMethod("eat", String.class, int.class);

        //调用方法,  method.invoke(被反射类实例对象, 对应前面参数列表的具体参数值)
        eat.invoke(dog5, "meat", 5);

        //2. 获取私有的eat方法,
        Method eatShit = clazz5.getDeclaredMethod("eatShit", String.class);
        //获取被反射类的实例对象
        //调用方法
        eatShit.invoke(dog5, "xi lan hua");
    }
}

Guess you like

Origin blog.csdn.net/nmsLLCSDN/article/details/121737278