阅读材料,我将从五个角度来理解Java的反射机制

一、什么是 Java 反射机制

1. 定义

反射(Reflection)是 Java 实现动态编程的核心机制:程序运行期间,可以动态获取任意类的全部元数据(类名、构造器、成员变量、成员方法、注解、父类、接口等),同时能动态创建对象、调用方法、读写字段,甚至突破private访问限制操作私有成员。

正常面向对象是正向操作:编译期提前导入类、new 对象调用方法;反射是反向操作:运行时才解析类的结构,无需提前硬编码类名。

2. 核心原理:Class 对象

JVM 加载任意类后,会在方法区生成唯一的Class对象,该对象存储当前类的所有结构信息,是反射操作的唯一入口。

Class类特性:final不可继承、只能由 JVM 自动创建、一个类全局仅存在一个 Class 实例。

二、三种获取 Class 对象的方式

方式 1:类名.class(编译期获取,性能最优)

Class<User> clazz = User.class;

方式 2:对象.getClass ()(已有实例时使用)

User user = new User();

Class<? extends User> clazz = user.getClass();

方式 3:Class.forName ("全类名")(运行时动态加载,框架最常用)

Class<?> clazz = Class.forName("com.demo.User");

三、反射的优缺点

优点

  1. 高灵活性:运行时动态加载类、创建对象,无需编译期固定代码,适配配置化开发。
  2. 解耦框架设计:Spring IoC、MyBatis、SpringMVC 等框架底层全部依赖反射实现,实现配置与业务代码分离。
  3. 通用工具封装:通用序列化、对象拷贝工具类依赖反射遍历对象字段。

缺点

  1. 性能损耗:反射需要解析字节码、绕过编译期优化,执行速度比直接 new / 方法调用慢数倍;高频场景建议缓存反射对象。
  2. 破坏封装性:通过setAccessible(true)可强行访问私有变量 / 方法,违背面向对象封装原则,存在安全风险。
  3. 编译期校验失效:编译时不会检查类名、方法名是否存在,错误只会在运行时抛出异常,增加调试成本。
  4. 安全限制:高版本 JDK(Java9+)模块化后,反射访问内部类会触发模块访问报错。

五、实际应用场景

  1. Spring 框架IoC 容器通过反射实例化 Bean、自动注入属性;AOP 动态代理底层依赖反射调用目标方法。
  2. ORM 框架(MyBatis):读取数据库结果集后,通过反射自动创建实体对象、给字段赋值,无需手动封装数据。
  3. 通用工具类:JSON 序列化(FastJSON、Jackson)、对象属性拷贝工具,通过反射遍历所有字段完成转换。
  4. 单元测试:JUnit 通过反射调用@Test标记的测试方法。
  5. 插件化开发:读取配置文件中的类全名,动态加载第三方插件类。