- 加载类元信息
- JVM 确保反射请求的类已经被加载,否则通过 Java 类加载过程实验 将 .class 文件加载到内存中。在这之后,类的所有元数据信息会存在 JVM 元数据区
- 获取 Class 对象
- JVM 为每个加载的类在堆内存中创建对应的 java.lang.Class 对象实例,作为反射操作的入口,后续的 如 getMethod 操作都是通过这个对象实现的
- 查找元数据
- 调用 Class 对象的方法 如 getDeclaredMethod 来获取特定的方法、字段或构造器时,JVM 需要去元数据区找对应的信息
- 创建反射对象
- 找到对应的元数据后,JVM 会创建对应的反射对象 Method、Field、Constructor等,这些对象提供了运行时检查和操作类成员的能力
- 执行操作(如 Method.invoke)
- JVM 先进行访问权限检查,然后对参数列表进行处理和校验、JVM要找到目标方法的实际执行入口
- 为什么慢?
- 动态解析和查找开销:正射在编译或者类加载的阶段就能确定大部分调用目标,反射则需要在运行时去元数据区进行搜索查找
- JIT 优化受限:无法享受 JIT 带来的方法内链,逃逸分析,锁优化等优化
- 类型检查开销:如 invoke 参数的类型检查,正射在编译期间确定
- 安全检查开销:private 字段等
- 参数和返回值的装箱拆箱