缓存Method和Field是提升Java反射性能最直接的方式,需按类+签名构造唯一键、用ConcurrentHashMap存储、静态预加载并setAccessible、封装工具类统一管理,注意热部署和多ClassLoader导致的缓存失效。

缓存 Method 和 Field 是提升 Java 反射性能最直接、见效最快的方式。核心逻辑很简单:把“查一次”的开销变成“查一次,用一百次”,避开每次调用都重复解析类结构、匹配签名、校验权限的高成本操作。
缓存粒度必须精确到类+签名
只缓存方法名或字段名会出错——比如同名不同参的方法(setValue(String) 和 setValue(int))会被覆盖。正确做法是构造唯一键:
- Method 缓存键示例:
com.example.User#getName()、com.example.User#setName(java.lang.String) - Field 缓存键示例:
com.example.User#id、com.example.User#name - 推荐用
ConcurrentHashMap<String, Method>或ConcurrentHashMap<String, Field>存储,线程安全且并发性能好
静态初始化时预加载 + setAccessible(true)
不要等到业务执行时才去反射查找。在类加载阶段就完成关键元数据的获取和权限开放:
- 声明
private static final Method GET_ID = User.class.getDeclaredMethod("getId"); - 配合
static { GET_ID.setAccessible(true); }一次性解除访问限制 - 后续所有
GET_ID.invoke(obj)都跳过查找、签名比对、安全管理器校验三重开销
封装统一工具类屏蔽细节
避免每个业务类都写重复缓存逻辑。提供一个轻量工具类,例如:
立即学习“Java免费学习笔记(深入)”;
- 对外暴露
ReflectUtils.getMethod(Class, String, Class...),内部自动按签名查缓存或首次加载 - 支持设置最大缓存数量,防止元空间(Metaspace)被大量反射对象占用
- 可选开启命中率统计(如
cacheHitCount / totalLookup),方便评估优化效果
注意缓存失效的典型场景
缓存不是一劳永逸,以下情况会导致缓存失效甚至运行异常:
- 热部署环境(如 Spring Boot DevTools)中类被重新加载,旧 Method 对象指向已卸载的类,调用会抛
IllegalAccessException - 使用多个 ClassLoader 加载同一类(如 OSGi、模块化应用),Class 对象不等价,缓存需按 ClassLoader 隔离
- 框架已内置缓存(如 Spring 的
ReflectionUtils),优先复用,避免重复实现



















