Skip to content

什么是反射?应用?

什么是反射

  • 定义
  • 反射(Reflection)是 Java 的一种运行时机制,允许程序动态获取类的信息(如字段、方法、构造器)并操作它们,即使这些信息在编译时未知。
  • 核心
  • 通过 java.lang.reflect 包实现,基于 Class 对象。

应用

  1. 动态调用:运行时调用方法或构造对象。
  2. 框架开发:如 Spring、Hibernate 的依赖注入和 ORM。
  3. 调试与测试:访问私有成员。
  4. 序列化:对象转 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. 反射的特点

优点

  • 灵活性
  • 运行时决定行为。
  • 通用性
  • 处理未知类。

缺点

  • 性能
  • 反射慢于直接调用(方法查找、权限检查)。
  • 安全性
  • 可破坏封装(如访问私有)。
  • 可读性
  • 代码复杂,调试难。

性能优化

  • 缓存 MethodField 对象。
  • 避免频繁反射。

4. 延伸与面试角度

  • 实现原理
  • JVM 加载类时生成 Class 对象,存储在方法区。
  • 与代理对比
  • 动态代理(Proxy)基于反射实现。
  • 实际案例
  • Spring IOC:反射实例化。
  • JUnit:反射调用 @Test 方法。
  • 面试点
  • 问“定义”时,提 Class 和动态性。
  • 问“应用”时,提框架和测试。

总结

反射是 Java 运行时获取和操作类信息的机制,核心靠 Class 对象。应用包括动态调用、框架开发等,灵活但性能较低。面试时,可写简单反射代码或提 Spring 示例,展示理解深度。