一、反射的定义
反射(Reflection)是Java在运行时动态获取类信息和操作类对象的能力。通过反射,可以在程序运行时:
- 获取类的名称、方法、属性、构造器等元数据。
- 创建对象实例。
- 调用方法或访问属性(包括私有成员)。
- 动态代理、注解处理等。
二、反射的核心类
Java反射API位于java.lang.reflect
包,核心类包括:
Class<T>
:表示类的元数据,是反射的入口。Constructor<T>
:类的构造方法。Method
:类的方法。Field
:类的属性(字段)。Modifier
:解析访问修饰符(如public
、private
)。
三、反射的基本使用步骤
获取
Class
对象:三种方式:Class<?> clazz1 = Class.forName("全限定类名"); // 通过类路径加载 Class<?> clazz2 = 对象.getClass(); // 通过实例对象获取 Class<?> clazz3 = 类名.class; // 直接通过类字面量
创建对象实例:
// 调用无参构造器(已过时,建议明确获取构造器) Object obj1 = clazz.newInstance(); // 推荐方式:获取构造器并实例化 Constructor<?> constructor = clazz.getDeclaredConstructor(); Object obj2 = constructor.newInstance();
操作方法和属性:
调用方法:
Method method = clazz.getMethod("方法名", 参数类型.class); method.invoke(obj, 参数值); // 调用方法
访问属性:
Field field = clazz.getDeclaredField("属性名"); field.setAccessible(true); // 允许访问私有属性 field.set(obj, 值); // 修改属性值
四、反射的典型应用场景
- 框架开发:如Spring的IoC容器(动态创建Bean)、Hibernate的ORM映射。
- 动态代理:如AOP中的拦截器。
- 注解处理:如JUnit通过反射查找带有
@Test
注解的方法。 - 工具类:如IDE的代码提示、调试工具。
五、反射的优缺点
优点:
- 灵活性:动态加载类、实现通用逻辑(如JSON序列化)。
- 突破封装:可访问私有成员(需谨慎使用)。
缺点:
- 性能开销:反射操作比直接调用慢(JVM优化后差距缩小)。
- 安全性问题:破坏封装性,可能引发安全问题。
- 维护困难:反射代码可读性差,且依赖类的内部细节。
六、示例代码
// 1. 获取Class对象
Class<?> clazz = Class.forName("com.example.Person");
// 2. 创建实例(假设有无参构造器)
Object person = clazz.getDeclaredConstructor().newInstance();
// 3. 访问私有属性
Field nameField = clazz.getDeclaredField("name");
nameField.setAccessible(true);
nameField.set(person, "张三");
// 4. 调用公共方法
Method sayHelloMethod = clazz.getMethod("sayHello");
sayHelloMethod.invoke(person);
// 5. 调用私有方法
Method privateMethod = clazz.getDeclaredMethod("privateMethod");
privateMethod.setAccessible(true);
privateMethod.invoke(person);
七、注意事项
- 异常处理:需处理
ClassNotFoundException
、NoSuchMethodException
、IllegalAccessException
等异常。 - 性能优化:频繁使用的反射操作可缓存
Class
、Method
等对象。 - 安全限制:在安全管理器下,反射可能受限。
评论 (0)