八股-反射

反射

反射 = 通过类名获取 JVM 中的 Class 实例 → 进而创建该类的对象 或 获取其方法/字段/构造器等信息。

1
2
3
4
5
6
7
8
// 1. 根据类名获取 Class 实例(JVM 已加载的)
Class<?> clazz = Class.forName("java.util.ArrayList");

// 2. 通过 Class 实例创建**对象**
Object obj = clazz.newInstance(); // 创建 ArrayList 实例

// 3. 或获取类信息
Method[] methods = clazz.getDeclaredMethods(); // 获取所有方法

什么是反射?

反射(Reflection) 允许程序在运行时动态地检查、修改或调用类、方法、属性、构造函数等代码结构的信息。

打破了传统”编译时绑定”的限制,适配未知或变化的类型,增加程序的灵活性和通用性。


反射的本质

  • JVM 为每个加载的 classinterface 创建对应的 Class 实例,保存其所有信息
  • 获取 Class 实例后,即可获取该类的全部信息(方法、字段、构造器等)
  • 通过 Class 实例获取类信息的方式称为反射
  • JVM 动态加载 class,可在运行期根据条件控制加载

使用场景

场景 说明
框架开发 Spring 的依赖注入、AOP 的动态代理
动态加载类 插件化架构,运行时加载外部模块
序列化/反序列化 JSON 库(如 Gson、Jackson)对象与字符串互转
测试工具 JUnit 动态调用测试方法

注意事项与避坑方案

反射的风险

风险 说明
性能开销 反射操作比直接调用慢(绕过 JVM 优化)
安全风险 可访问私有成员,破坏封装性
维护困难 代码可读性差,编译期无法检查,调试复杂

避坑方案

方案 实践
高频场景避免直接使用 用 MyBatis-Plus 的 Lambda 查询替代反射拼接 SQL
缓存反射对象 缓存获取的 Method/Field 对象(Spring 内部做法)
使用优化框架 用 CGLIB、ASM 替代原生反射