章节导读
大翔(项目总监):"小崔,上次需求评审会提到的那个通用DAO层,你怎么实现?不同实体类的字段都不一样,你总不能每个实体都写一套增删改查吧?"
白歌(架构师):"用反射。JDK提供了在运行时检查类结构、调用方法甚至修改私有字段的能力。这正是实现框架级代码的基础——Spring的IoC容器、MyBatis的结果映射、JUnit的测试执行,底层全是反射。"
小崔(后端开发):"听起来很强大……但它不会是破坏封装的黑魔法吗?"
白歌:"问得好。反射确实能绕过访问控制,但这正是框架存在的意义——在特定的受控场景下,用框架替应用开发者处理那些他们不应该手动处理的底层细节。关键是知道什么时候用,以及怎么用得安全高效。"
本章定位
反射(Reflection)是Java语言中最强大的特性之一,也是区分"会用Java"和"理解Java"的分水岭。本章深入JDK 8反射机制的核心API,从Class对象到Constructor/Field/Method的完整操作链,并最终通过手写一个简易DI容器将知识落地。
| 文件 | 核心内容 | 难度 |
|---|---|---|
| 反射概述与Class对象 | 反射的本质(运行时类型信息RTTI)、Class对象的四种获取方式、类加载与Class对象的关系 | ★★★ |
| Constructor与对象创建 | 获取构造方法、newInstance()创建对象、setAccessible()绕过访问控制 | ★★★☆ |
| Field与Method操作 | 字段读写、方法调用、InvocationTargetException处理、私有成员访问 | ★★★★ |
| 反射的应用与性能 | 简易DI容器实现、ORM映射、反射性能开销与优化策略 | ★★★★★ |
为什么需要反射?
在传统编程中,代码在编译时就知道自己要操作哪个类:
// 编译时绑定——一切在编译期就确定了
Student student = new Student();
student.setName("小崔");
但框架开发者面对的不是具体的Student或Teacher,而是未知的、任意的类。框架必须做到:
- 扫描classpath下的所有
@Component注解类并实例化(Spring IoC) - 将数据库表的列名自动映射到Java对象的字段(MyBatis / Hibernate)
- 读取配置文件中的类名并动态创建对象(插件系统)
- 不修改源码即可调用目标对象的任意方法(RPC框架)
这些需求的核心是:在运行时获取类的信息,并在运行时操作类的成员。这就是反射。
本章知识图谱
学习建议
- 动手优先:每个代码示例都完整可运行,建议拷贝到IDE中执行并修改参数观察变化。
- 理解底层:不要只记API,要理解
native方法背后的JVM机制(方法区、Klass模型)。 - 关注异常:反射API几乎每个方法都声明了受检异常,理解每种异常的触发条件是避免线上故障的关键。
- 性能意识:反射比直接调用慢几十倍,学完本章要知道如何缓存和优化。
大翔(总结):"框架是骨架,反射就是骨架里的关节。不掌握反射,你永远只能做框架的使用者,成不了框架的设计者。"
前置知识
- 类加载机制(双亲委派、类加载阶段)
- JVM内存结构(方法区、堆、栈)
- 泛型(类型擦除)
- 注解(
@Retention、@Target) - 异常处理(受检异常与非受检异常)
如果你对以上知识点有生疏,建议先回顾相关章节,尤其是类加载机制——它是理解Class对象的基石。