Java反射本质是运行时通过Class对象动态操作类的机制,它支持动态加载类、突破访问限制、创建对象及调用方法,广泛用于JDBC、Spring、MyBatis等框架,但存在性能开销大、破坏封装、绕过安全检查等风险,需结合场景权衡使用。

Java 反射是大厂面试高频考点,重点不在背API,而在理解原理、识别风险、结合真实场景分析利弊。面试官常通过反射题考察你对JVM机制、类加载、安全模型的理解深度,以及工程化思维。
反射的核心能力与典型考法
面试中常问“反射能做什么”,但高分回答要分层展开:
-
运行时获取类信息:比如通过
Class.forName("com.example.User")动态加载类,不依赖编译期引用——这是SPI、JDBC驱动加载的基础 -
突破访问限制:用
setAccessible(true)调用private方法或字段,但JDK 9+模块系统下会受--illegal-access策略限制 - 动态创建对象与调用:替代new和硬编码方法调用,Spring AOP代理、JSON反序列化(如Jackson)底层都依赖此能力
必被追问的性能与安全问题
不能只说“反射慢”,要讲清为什么慢、慢在哪、怎么缓解:
- 每次反射调用都需解析字节码、校验权限、生成字节码桩(JDK 8前),比直接调用慢10–100倍
- JDK 7起引入
MethodHandle和VarHandle,配合Lookup可绕过部分检查,性能接近直接调用 - 安全风险不止于private暴露:反射可绕过SecurityManager(若启用)、破坏单例、干扰final语义,金融/支付类系统通常禁用反射序列化
结合源码与框架的真实案例
光讲理论容易空洞,面试官更想听你联系实际:
立即学习“Java免费学习笔记(深入)”;
- MyBatis中
ResultSetHandler用反射将数据库结果映射到POJO,但会缓存Field和Method对象避免重复查找 - Spring BeanFactory在注入时,对
@Autowired字段先用反射获取Field,再用field.set(obj, value)赋值 - Lombok的
@Data注解在编译期生成getter/setter,就是为规避运行时反射开销——这是典型的“编译期优化替代反射”思路
如何写出让人眼前一亮的答案
避免罗列API,用对比+权衡+落地建议收尾:
- 说清楚“什么场景该用”:配置驱动型逻辑(如规则引擎)、通用工具类(如对象深拷贝)、测试Mock
- 强调“什么场景不该用”:高频核心路径(如交易下单)、强安全要求模块、Android低版本(反射受限且耗电)
- 提一个具体优化技巧:用
Method.invoke()前先缓存Method对象;或用Unsafe.allocateInstance()(慎用)跳过构造器调用


















