文章目录
一、反射机制的理解:基本概念
Java 的反射机制(Reflection)允许程序在运行时动态地获取类的信息并操作类或对象的属性、方法、构造器等。它的核心是打破编译时的静态限制,实现动态行为。虽然反射可能带来性能开销和安全隐患,但在某些场景下非常有用,以下是一些典型应用场景:
1、反射的核心用途
---- 动态获取类信息
---- 动态创建对象
---- 动态调用方法
---- 动态修改字段
-
动态获取类信息
在运行时分析类的结构(如类名、方法、字段、注解等),无需提前知道类的具体定义。 -
动态创建对象
根据类名(可能是配置文件中的字符串)创建对象实例。 -
动态调用方法
在运行时调用对象的任意方法,甚至私有方法(需突破访问限制)。 -
动态修改字段
访问或修改对象的字段(包括私有字段)。
2、常见应用场景(框架设计、单元测试、动态代理、插件式开发架构、IDE自动代码提示)
-
框架设计(如Spring、Hibernate)
- 依赖注入(DI)
Spring 通过反射读取 @Autowired 等注解,动态创建对象并注入依赖。 - 配置文件驱动
通过 XML 或注解配置类名,框架在运行时反射加载类并实例化对象。 - 事务管理/AOP动态代理
基于反射生成代理对象,拦截方法调用(如事务控制、日志)。
- 依赖注入(DI)
-
单元测试(如JUnit)
- JUnit 通过反射扫描测试类,识别带有 @Test 注解的方法并动态调用。
-
IDE 工具
- IDE 的代码补全、调试器查看对象字段值等功能依赖反射获取类信息。
-
动态代理
- 实现 InvocationHandler 接口,在运行时生成代理类,拦截方法调用(如 RPC 框架的远程调用)。
-
插件化架构
- 通过反射动态加载外部 JAR 中的类,实现热插拔功能。
3、简单代码示例
具体的反射里面的语法细节参考反射、动态代理这篇博客
示例1:反射创建对象并调用方法
// 假设类名和方法名来自配置文件
String className = "com.example.User";
String methodName = "sayHello";
// 反射创建对象
Class<?> clazz = Class.forName(className);
Object obj = clazz.getDeclaredConstructor().newInstance();
// 反射调用方法
Method method = clazz.getMethod(methodName);
method.invoke(obj);
示例2:Spring 风格的依赖注入(简化版)
public class Container {
private Map<String, Object> beans = new HashMap<>();
pu