反射是jvm提供的运行时自省机制,核心是class对象——它是类的运行时表示,所有信息都从它出发;广泛用于spring bean创建、jdbc驱动加载等场景,但存在性能开销大、破坏封装、泛型擦除等风险,需权衡使用。

大厂面试里考反射,不是让你背Class.forName怎么写,而是看你能不能说清它“为什么存在”、“在哪儿真用”、“用的时候踩过什么坑”。掌握这三点,比堆砌 API 更管用。
理解反射的本质:不是“黑魔法”,而是 JVM 的自省能力
反射不是 Java 特有的技巧,它是程序在运行时“照镜子”的能力——通过 Class 对象 查看自己或别的类长什么样。关键要明白:
• 每个类加载进 JVM 后,都会生成唯一对应的 Class 实例,它是反射的起点;
• 反射操作(比如调用私有方法)本质是绕过编译期检查,在运行期由 JVM 安全机制临时放行;
• 它不改变字节码,也不生成新类,只是动态触发已有逻辑。
抓住高频实战场景:别只讲理论,要能对应到框架源码
面试官爱问“Spring 是怎么靠反射创建 Bean 的?”,答案不能只说“用了 newInstance”,得拆解链条:
• Spring 读取配置或注解后,拿到类名字符串 → Class.forName() 加载类;
• 用 getDeclaredConstructor() 找构造器(包括 private)→ setAccessible(true) 破开访问限制;
• 调用 newInstance() 或 constructor.newInstance() 实例化;
• 再用 Field.set() 注入依赖(同样需 setAccessible)。
类似地,JDBC 的 Class.forName("com.mysql.cj.jdbc.Driver") 是为了触发静态块注册驱动,这也是反射的典型用途。
说清代价与边界:性能、安全、泛型擦除一个都不能漏
光会用不叫懂反射,能判断“该不该用”才是重点:
• 性能上:反射调用比直接调用慢 5–10 倍(涉及权限检查、参数封装、类型匹配),高频路径(如循环内)必须避免;
• 封装性:setAccessible(true) 会失效 SecurityManager(如果启用),且破坏设计契约,生产环境慎用;
• 泛型问题:运行时泛型已擦除,ArrayList
• final 字段:可 setAccessible + set 修改,但对编译期常量(如 static final String s = "abc")无效,因值已被内联。
准备面试话术:用一句话讲清原理,再举一个你改过的 bug
别一上来就列三种获取 Class 的方式。试试这样组织回答:
• “反射是 JVM 提供的运行时自省机制,核心是 Class 对象 —— 它是类的运行时表示,所有信息都从它出发。”
• “我上次排查一个 MyBatis 参数绑定失败的问题,发现是实体类字段用了 Lombok @Getter 但没加 @Accessors(chain = true),导致反射 getMethod() 找不到符合命名规范的 getter,最后加了注解解决。”
• “所以我认为,反射不是炫技工具,而是框架‘读懂你代码’的桥梁;用得好提升扩展性,用不好就成了隐藏的性能雷和维护债。”
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











