阅读 9

Java基础之反射

反射基本介绍

基本过程:

1、编译 Java 文件,生成.class 文件

2、使用 Java 虚拟机(JVM)将字节码文件(字节码文件在内存中使用 Class 类表示)加载到内存

4、使用反射的时候,首先获取到 Class 类,就可以得到 class 文件里的所有内容,包含属性、构造方法、普通方法

5、属性通过 Filed 类表示、构造方法通过 Constructor 表示、普通方法通过 Method 表示

API 学习

接口定义

public interface Pc {
    void run();
}
复制代码

实现类

public class Dell implements Pc {

    // 私有变量
    private String cpu;

    public int price;

    // 无参构造方法
    public Dell() {
    }

    // 有构造方法
    public Dell(String cpu) {
        this.cpu = cpu;
    }

    @Override
    public void run() {
        System.out.println("Dell PC");
    }

    public String getCpu() {
        return cpu;
    }

    public void setCpu(String cpu) {
        this.cpu = cpu;
    }

    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        this.price = price;
    }

    // 私有方法
    private void desc() {
        System.out.println("私有方法: 散热不好");
    }
}
复制代码

API 学习

@Slf4j
public class ReflectEntrance {
    public static void main(String[] args) throws Exception{

        // 1. Class.forName()
        Class<?> dClazz = Class.forName("com.example.ref.Dell");
        log.info("Class.forName()=======:{}", dClazz);

        // 2. 类名.class
        Class<Dell> dClazz2 = Dell.class;
        log.info("类名.class=======:{}", dClazz);

        // 3. 对象.getClass()
        Dell dell = new Dell();
        Class<?> dClazz3 = dell.getClass();
        log.info("对象.getClass()=======:{}", dClazz3);

        System.out.println("\r");

        // 获取所有的公共方法(没有private),但是有它所有有关联的类的方法,包括接口,它的父类Object
        Method[] methods = dClazz.getMethods();
        for (Method method: methods) {
            log.info("dClazz.getMethods()=======:{}", method.getName());
        }

        System.out.println("\r");

        // 可以得到当前类的所有的方法: 包括私有的方法
        Method[] declaredMethods = dClazz.getDeclaredMethods();
        for(Method method : declaredMethods)
            log.info("dClazz.getDeclaredMethods()=======:{}", method.getName());

        System.out.println("\r");

        // 获取Dell实现的所有的接口
        Class<?>[] interfaces = dClazz.getInterfaces();
        for(Class<?>inter : interfaces)
            log.info("dClazz.getInterfaces()=======:{}", inter);

        System.out.println("\r");

        // 获取公共变量
        Field[] fields = dClazz.getFields();
        for(Field field : fields)
            log.info("dClazz.getFields()=======:{}", field);

        System.out.println("\r");

        // 获取私有变量
        Field[] declaredFields = dClazz.getDeclaredFields();
        for(Field field : declaredFields)
            log.info("dClazz.getDeclaredFields()=======:{}", field.getName());

        System.out.println("\r");

        // 获取构造器
        Constructor<?>[] constructors = dClazz.getConstructors();
        for (Constructor<?> c : constructors)
            log.info("dClazz.getConstructors()=======:{}", c);

        System.out.println("\r");

        // 获取父类
        Class<?> superclass = dClazz.getSuperclass();
        log.info("dClazz.getSuperclass()=======:{}", superclass); // 默认就是Object

        System.out.println("\r");

        // 用反射创建实例
        Dell dell1 = (Dell)dClazz.newInstance();
        log.info("dClazz.newInstance()=======:{}", dell1);
        dell1.run();

        System.out.println("\r");

        // 设置变量
        Field cpu = dClazz.getDeclaredField("cpu");
        cpu.setAccessible(true);
        cpu.set(dell1, "intel");
        log.info("设置变量=======:{}", dell1.getCpu());

        System.out.println("\r");

        // 调用方法
        Method setCpu = dClazz.getDeclaredMethod("setCpu", String.class);
        setCpu.setAccessible(true);
        setCpu.invoke(dell1, "AMD");
        log.info("调用方法=======:{}", dell1.getCpu());

        System.out.println("\r");

        // 操作构造方法
        Constructor<?> declaredConstructor = dClazz.getDeclaredConstructor(String.class);
        Dell hw = (Dell)declaredConstructor.newInstance("华为");
        log.info("构造方法=======:{}", hw.getCpu());

    }
}
复制代码

输出结果

23:24:02.109 [main] INFO com.example.ref.ReflectEntrance - Class.forName()=======:class com.example.ref.Dell
23:24:02.117 [main] INFO com.example.ref.ReflectEntrance - 类名.class=======:class com.example.ref.Dell
23:24:02.117 [main] INFO com.example.ref.ReflectEntrance - 对象.getClass()=======:class com.example.ref.Dell

23:24:02.118 [main] INFO com.example.ref.ReflectEntrance - dClazz.getMethods()=======:run
23:24:02.118 [main] INFO com.example.ref.ReflectEntrance - dClazz.getMethods()=======:getPrice
23:24:02.118 [main] INFO com.example.ref.ReflectEntrance - dClazz.getMethods()=======:setPrice
23:24:02.118 [main] INFO com.example.ref.ReflectEntrance - dClazz.getMethods()=======:setCpu
23:24:02.118 [main] INFO com.example.ref.ReflectEntrance - dClazz.getMethods()=======:getCpu
23:24:02.118 [main] INFO com.example.ref.ReflectEntrance - dClazz.getMethods()=======:wait
23:24:02.118 [main] INFO com.example.ref.ReflectEntrance - dClazz.getMethods()=======:wait
23:24:02.118 [main] INFO com.example.ref.ReflectEntrance - dClazz.getMethods()=======:wait
23:24:02.118 [main] INFO com.example.ref.ReflectEntrance - dClazz.getMethods()=======:equals
23:24:02.118 [main] INFO com.example.ref.ReflectEntrance - dClazz.getMethods()=======:toString
23:24:02.118 [main] INFO com.example.ref.ReflectEntrance - dClazz.getMethods()=======:hashCode
23:24:02.118 [main] INFO com.example.ref.ReflectEntrance - dClazz.getMethods()=======:getClass
23:24:02.118 [main] INFO com.example.ref.ReflectEntrance - dClazz.getMethods()=======:notify
23:24:02.118 [main] INFO com.example.ref.ReflectEntrance - dClazz.getMethods()=======:notifyAll

23:24:02.118 [main] INFO com.example.ref.ReflectEntrance - dClazz.getDeclaredMethods()=======:run
23:24:02.118 [main] INFO com.example.ref.ReflectEntrance - dClazz.getDeclaredMethods()=======:desc
23:24:02.118 [main] INFO com.example.ref.ReflectEntrance - dClazz.getDeclaredMethods()=======:getPrice
23:24:02.118 [main] INFO com.example.ref.ReflectEntrance - dClazz.getDeclaredMethods()=======:setPrice
23:24:02.118 [main] INFO com.example.ref.ReflectEntrance - dClazz.getDeclaredMethods()=======:setCpu
23:24:02.118 [main] INFO com.example.ref.ReflectEntrance - dClazz.getDeclaredMethods()=======:getCpu

23:24:02.118 [main] INFO com.example.ref.ReflectEntrance - dClazz.getInterfaces()=======:interface com.example.ref.Pc

23:24:02.119 [main] INFO com.example.ref.ReflectEntrance - dClazz.getFields()=======:public int com.example.ref.Dell.price

23:24:02.119 [main] INFO com.example.ref.ReflectEntrance - dClazz.getDeclaredFields()=======:cpu
23:24:02.119 [main] INFO com.example.ref.ReflectEntrance - dClazz.getDeclaredFields()=======:price

23:24:02.119 [main] INFO com.example.ref.ReflectEntrance - dClazz.getConstructors()=======:public com.example.ref.Dell()
23:24:02.119 [main] INFO com.example.ref.ReflectEntrance - dClazz.getConstructors()=======:public com.example.ref.Dell(java.lang.String)

23:24:02.119 [main] INFO com.example.ref.ReflectEntrance - dClazz.getSuperclass()=======:class java.lang.Object

23:24:02.120 [main] INFO com.example.ref.ReflectEntrance - dClazz.newInstance()=======:com.example.ref.Dell@3a5ed7a6
Dell PC

23:24:02.120 [main] INFO com.example.ref.ReflectEntrance - 设置变量=======:intel

23:24:02.121 [main] INFO com.example.ref.ReflectEntrance - 调用方法=======:AMD

23:24:02.121 [main] INFO com.example.ref.ReflectEntrance - 构造方法=======:华为
复制代码

简单演示场景

我们做一个对象转 map 的演示:

public class User {

    private String username;
    private String password;

    public User(String username, String password) {
        this.username = username;
        this.password = password;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}
复制代码

通过反射操作字段变量

@Slf4j
public class Test {


    public <T> Map<String, Object> obj2map(T o) throws IllegalAccessException {

        Class<?> aClass = o.getClass();
        Field[] declaredFields = aClass.getDeclaredFields();

        Map<String,Object> map = new HashMap<String, Object>();

        for (int j = 0; j < declaredFields.length; j++) {
            Field declaredField = declaredFields[j];

            // 获取属性
            String key = declaredField.getName();
            declaredField.setAccessible(true);
            // 获取属性值
            Object value = declaredField.get(o);

            log.info("key={}, value={}", key, value.toString());

            map.put(key, value);
        }
        return map;
    }

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

        Test test = new Test();
        User user = new User("admin", "123456");
        Map<String, Object> map = test.obj2map(user);
        log.info(map.toString());

    }
}
复制代码

输出

23:52:41.964 [main] INFO com.example.poi.Test - key=username, value=admin
23:52:41.970 [main] INFO com.example.poi.Test - key=password, value=123456
23:52:41.970 [main] INFO com.example.poi.Test - {password=123456, username=admin}
复制代码

最后

本文到此结束。感谢阅读,如果您觉得不错,请关注公众号【当我遇上你】支持一下。