反射原理与应用场景
面试官问:"Java 反射是什么?用过吗?"
候选人小郑答:"反射是在运行时动态获取类的信息,比如类名、方法、字段等。"
面试官追问:"那 Class 对象是什么时候创建的?类加载的时候还是第一次使用时?"
小郑说:"应该是类加载的时候?"
面试官写了一段代码:
小郑答不上来。
【面试官心理】 这道题考的是候选人对类加载时机和 Class 对象创建的理解。能说出"加载-链接-初始化"流程的候选人,是真正看过 JVM 规范的。
一、反射的核心:Class 对象 🔴
1.1 三种获取 Class 对象的方式
⚠️
Class.forName() 默认会触发类初始化(执行 static 块),而 .class 不会。在 JDBC 驱动注册中必须用 Class.forName("com.mysql.jdbc.Driver") 正是利用了这个特性来触发驱动的 static 初始化块。
1.2 Class 对象的创建时机
Class 对象是类加载过程中创建的:
类加载(Loading)阶段:ClassLoader 读取 .class 文件,生成 Class 对象,放入方法区。
二、反射的核心 API 🔴
2.1 获取类信息
2.2 动态创建对象
2.3 动态调用方法
2.4 动态访问字段
三、应用场景 🔴
3.1 Spring 框架的反射应用
3.2 Hibernate/MyBatis 的反射应用
3.3 Jackson/Gson 的反射应用
3.4 通用对象拷贝工具
四、反射的性能代价 🔴
4.1 性能问题来源
4.2 优化策略
💡
Spring 3.0+、MyBatis、Hibernate 等框架都使用了反射缓存优化。能说出"缓存反射对象"作为优化策略的候选人,面试官会认为有框架源码阅读经验。
五、安全问题(模块化)
JDK 9 模块系统引入了更严格的反射限制:
【面试官心理】 能说出 JDK 9 模块化对反射限制的候选人,说明关注了 Java 演进方向。这是 P6/P7 的加分点。
六、追问升级
面试官:"getDeclaredFields 和 getFields 有什么区别?"
关键区别:getFields() 只返回 public 字段(包括继承的),getDeclaredFields() 返回本类声明的所有字段(包括 private)。