外观
一句话答案
反射在运行时获取类信息并操作其成员(字段/方法/构造器),是 Spring IoC/AOP、ORM 框架的基础,但有性能开销。
核心要点
Java 有四种引用强度(从强到弱):
| 引用类型 | 类 | GC 行为 | 典型使用场景 |
|---|---|---|---|
| 强引用(Strong) | 默认 Object obj = new Object() | 永远不会被 GC 回收 | 普通对象使用 |
| 软引用(Soft) | SoftReference<T> | 内存不足(OOM 前)才回收 | 内存敏感缓存 |
| 弱引用(Weak) | WeakReference<T> | 下次 GC 时必定回收 | WeakHashMap,避免内存泄漏 |
| 虚引用(Phantom) | PhantomReference<T> | 随时可能被回收,get() 永远返回 null | 跟踪对象被回收的时机,用于资源清理 |
实际应用:
ThreadLocal中 Entry 继承了WeakReference<ThreadLocal<?>>,当 ThreadLocal 对象被 GC 后,Entry 的 key 变为 null,便于 GC 回收(但 value 仍是强引用,这是内存泄漏的根源)- 图片缓存框架(如 Glide)使用软引用缓存 Bitmap
追问与易错
追问方向:
- 反射的性能开销在哪?(安全检查/方法查找/JIT 无法内联)
- Spring 为什么大量使用反射?(IoC 需要动态创建 Bean 和注入依赖)
- 如何优化反射性能?(setAccessible(true) / MethodHandle / 缓存 Method 对象)
易错点:
- ❌ "反射很慢不能用"——Spring 整个框架基于反射,热路径优化后影响不大
- ❌ 忘记 setAccessible(true) 绕过安全检查提升性能
💡 记忆锚点
四级引用像四道安全绳:强引用=焊死不放,软引用=OOM前才剪,弱引用=下次GC必剪(ThreadLocal的key就是这根绳),虚引用=绳已断只留个通知。