反射与动态代理:Class/Method/Field、安全边界与性能画像
大约 3 分钟
反射与动态代理:Class/Method/Field、安全边界与性能画像
新手一屏速览
- 反射访问受可访问性与模块化限制;需要
setAccessible(true)或opens - 高性能成员访问优先 MethodHandle/VarHandle;Method 比反射更轻,且可内联
- 缓存 Class/Method/Field/Handle;避免在热路径反射查找与字符串拼接
1. 基础访问
Class<?> c = Class.forName("com.example.User");
Constructor<?> ctor = c.getDeclaredConstructor();
ctor.setAccessible(true);
Object o = ctor.newInstance();
Field f = c.getDeclaredField("name"); f.setAccessible(true); f.set(o, "Tom");
Method m = c.getDeclaredMethod("hello"); m.setAccessible(true); m.invoke(o);2. MethodHandle 与 VarHandle
MethodHandles.Lookup lookup = MethodHandles.lookup();
MethodHandle mh = lookup.findVirtual(String.class, "length", MethodType.methodType(int.class));
int len = (int) mh.invokeExact("abc");- MethodHandle 更接近 JVM 层,优化空间更大;VarHandle 用于字段/数组原子或有序访问
3. 动态代理与字节码工具
- JDK 代理:基于接口
Proxy.newProxyInstance;类代理使用 ByteBuddy/CGLIB - AOP/拦截器/监控常用;注意类加载器与模块边界
4. 模块化与可访问性
- 强模块化限制非法反射;使用
opens或命令行--add-opens精细开放 - 在偏底层框架中,使用 MethodHandle 结合 Lookup 权限更可控
5. 性能与缓存
最近建一些几十个工作内推群,各大城市都有,群里目前已经收集了很多内推岗位,大厂、中厂、小厂、外包都有。 欢迎HR、开发、测试、运维和产品加入。

扫描下方微信,备注:网站+所在城市,即可拉你进工作内推群。

- 缓存 Class/Method/Field/Handle;避免重复查找与安全检查
- 反射创建对象/调用方法在热路径通常劣于直接调用;必要时生成专用代码或方法引用
6. 安全边界
- 控制可反射访问的包范围;避免对外暴露内部实现;对不可信输入严格校验
- 日志与审计反射关键路径,配合告警与开关
7. 练习
- 编写一个简易依赖注入容器,支持构造注入与字段注入(仅演示)
- 使用 MethodHandle/VarHandle 重写某字段 get/set 热路径,基准对比
示例代码(可直接复制运行)
示例一:基础反射访问(构造/字段/方法)
public class ReflectionBasics {
public static class User {
private String name;
public User() { this.name = "default"; }
public String hello() { return "Hello " + name; }
}
public static void main(String[] args) throws Exception {
Class<?> c = User.class;
Object o = c.getDeclaredConstructor().newInstance();
var f = c.getDeclaredField("name"); f.setAccessible(true); f.set(o, "Tom");
var m = c.getDeclaredMethod("hello"); m.setAccessible(true);
System.out.println(m.invoke(o));
}
}示例二:MethodHandle 调用成员方法
import java.lang.invoke.*;
public class MHCall {
public static void main(String[] args) throws Throwable {
MethodHandles.Lookup l = MethodHandles.lookup();
MethodHandle mh = l.findVirtual(String.class, "substring", MethodType.methodType(String.class, int.class, int.class));
String s = (String) mh.invokeExact("abcdef", 1, 4);
System.out.println(s); // bcd
}
}示例三:JDK 动态代理
import java.lang.reflect.*;
public class JdkProxyDemo {
interface Service { String hi(String name); }
static class RealService implements Service { public String hi(String n){ return "Hi " + n; } }
public static void main(String[] args) {
Service target = new RealService();
Service proxy = (Service) Proxy.newProxyInstance(
Service.class.getClassLoader(),
new Class<?>[]{Service.class},
(p, method, a) -> {
long t0 = System.nanoTime();
Object r = method.invoke(target, a);
long dt = System.nanoTime() - t0;
System.out.println("took " + dt/1_000_000.0 + " ms");
return r;
});
System.out.println(proxy.hi("world"));
}
}示例四:缓存反射元数据减少查找成本
import java.lang.reflect.*;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class ReflectionCache {
private static final Map<Class<?>, Method> HELLO = new ConcurrentHashMap<>();
static Method helloMethod(Class<?> c) {
return HELLO.computeIfAbsent(c, k -> {
try { var m = k.getDeclaredMethod("hello"); m.setAccessible(true); return m; }
catch (Exception e) { throw new RuntimeException(e); }
});
}
public static class T { public String hello(){ return "ok"; } }
public static void main(String[] args) throws Exception {
Method m = helloMethod(T.class);
System.out.println(m.invoke(new T()));
}
}