什么是反射?应用?
什么是反射
- 定义:
- 反射(Reflection)是 Java 的一种运行时机制,允许程序动态获取类的信息(如字段、方法、构造器)并操作它们,即使这些信息在编译时未知。
- 核心:
- 通过
java.lang.reflect
包实现,基于Class
对象。
应用
- 动态调用:运行时调用方法或构造对象。
- 框架开发:如 Spring、Hibernate 的依赖注入和 ORM。
- 调试与测试:访问私有成员。
- 序列化:对象转 JSON 或 XML。
1. 反射详解
(1) 基本原理
- Class 对象:
- 每个类加载后,JVM 生成唯一的
Class
实例,存储元信息。 - 获取方式:
Class.forName("类名")
。对象.getClass()
。类名.class
。- 操作:
- 获取字段(
getFields
)、方法(getMethods
)、构造器(getConstructors
)。 - 调用(
invoke
)、赋值(set
)。
(2) 示例
// 获取 Class 对象
Class<?> clazz = Class.forName("java.util.ArrayList");
// 创建实例
Constructor<?> constructor = clazz.getConstructor();
Object list = constructor.newInstance();
// 调用方法
Method addMethod = clazz.getMethod("add", Object.class);
addMethod.invoke(list, "hello");
// 访问字段(假设有 public 字段 size)
Field sizeField = clazz.getDeclaredField("size");
sizeField.setAccessible(true); // 私有需开启
sizeField.set(list, 10);
System.out.println(list); // [hello]
(3) 反射的本质
- 动态性:
- 编译时无需知道类名,运行时解析。
- 元数据:
Class
对象封装类的结构。
2. 反射的应用
(1) 动态调用
- 场景:
- 根据配置文件加载类或调用方法。
- 示例:
String className = "com.example.MyClass";
Class<?> cls = Class.forName(className);
Object obj = cls.getDeclaredConstructor().newInstance();
Method method = cls.getMethod("doSomething");
method.invoke(obj);
- 用途:
- 插件系统、动态代理。
(2) 框架开发
- Spring:
- 依赖注入:反射创建 Bean。
Class<?> beanClass = Class.forName("com.example.UserService");
Object bean = beanClass.getDeclaredConstructor().newInstance();
- Hibernate:
- ORM:反射映射字段到数据库列。
(3) 调试与测试
- 场景:
- 访问私有成员,测试内部状态。
- 示例:
class MyClass {
private String secret = "hidden";
}
MyClass obj = new MyClass();
Field field = MyClass.class.getDeclaredField("secret");
field.setAccessible(true);
System.out.println(field.get(obj)); // "hidden"
(4) 序列化
- 场景:
- 对象转 JSON(如 Gson)。
- 示例:
- 反射遍历字段,生成键值对。
- 用途:
- 数据传输、存储。
3. 反射的特点
优点
- 灵活性:
- 运行时决定行为。
- 通用性:
- 处理未知类。
缺点
- 性能:
- 反射慢于直接调用(方法查找、权限检查)。
- 安全性:
- 可破坏封装(如访问私有)。
- 可读性:
- 代码复杂,调试难。
性能优化
- 缓存
Method
或Field
对象。 - 避免频繁反射。
4. 延伸与面试角度
- 实现原理:
- JVM 加载类时生成
Class
对象,存储在方法区。 - 与代理对比:
- 动态代理(
Proxy
)基于反射实现。 - 实际案例:
- Spring IOC:反射实例化。
- JUnit:反射调用
@Test
方法。 - 面试点:
- 问“定义”时,提
Class
和动态性。 - 问“应用”时,提框架和测试。
总结
反射是 Java 运行时获取和操作类信息的机制,核心靠 Class
对象。应用包括动态调用、框架开发等,灵活但性能较低。面试时,可写简单反射代码或提 Spring 示例,展示理解深度。