Java Reflection

- 3 mins

简介

反射 (Reflection) 是 Java 语言中的一种特性,能够让程序在运行时,获取 class 的相关信息(如内部定义的方法、字段、实现的接口等)、创建 class 实例、调用方法、修改属性等,且这些操作可以在事先(如编译期)不知道类信息的情况下实现

使用场景

缺点

细节

java.lang.Class 是所有 Reflection API 的入口类

对于每个 object,JVM 都会实例化一个Class 实例,来提供运行时获取 object 属性、创建 objects 的能力

获取 Class 实例的几种方式

Class 相关方法

Class 相关方法调用后的返回值类型在 java.lang.reflect 包中定义,如

对于私有方法、属性等,在调用和修改时,需要先调用 setAccessible(true) 来关闭 access checks,否则会失败

示例

import org.junit.Test;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;


public class ReflectionTest {
    @Test
    public void testGetConstructs() {
        // 获取所有 public 构造方法
        Constructor[] constructors = HashMap.class.getConstructors();
        for (Constructor constructor : constructors) {
            System.out.println(constructor);
        }
        /**
         * 输出
         * public java.util.HashMap(int)
         * public java.util.HashMap()
         * public java.util.HashMap(java.util.Map)
         * public java.util.HashMap(int,float)
         */
    }

    @Test
    public void testNewInstance() throws Exception {
        // 使用 public java.util.HashMap(int) 构造方法来创建实例
        Constructor<HashMap> constructor = HashMap.class.getConstructor(new Class[]{int.class});
        Map map = constructor.newInstance(new Object[]{10});
        System.out.println(map.size());
    }

    @Test
    public void testGetDeclaredMethods() {
        // 获取当前类定义的所有方法
        Method[] methods = HashMap.class.getDeclaredMethods();
        for (Method method : methods) {
            System.out.println(method);
        }
        /**
         * public java.lang.Object java.util.HashMap.remove(java.lang.Object)
         * public boolean java.util.HashMap.remove(java.lang.Object,java.lang.Object)
         * ...
         * void java.util.HashMap.afterNodeRemoval(java.util.HashMap$Node)
         * void java.util.HashMap.internalWriteEntries(java.io.ObjectOutputStream) throws java.io.IOException
         */
    }

    @Test
    public void testInvokeMethod() throws Exception {
        Map<String, String> map = new HashMap<>();
        String key = "key";
        map.put(key, "any");
        Method method = HashMap.class.getMethod("get", Object.class);
        String value = (String) method.invoke(map, new Object[]{key});
        System.out.println(value);
    }

    @Test
    public void testInvokePrivateMethod() throws Exception {
        Constructor<Runtime> constructor = Runtime.class.getDeclaredConstructor(null);
        constructor.setAccessible(true);
        Runtime runtime = constructor.newInstance();
        System.out.println(runtime);
    }
}

参考

b1ngz
rss facebook twitter github weibo youtube mail spotify instagram linkedin google pinterest medium vimeo