Java反射机制:动态调用类方法与属性

Java反射机制允许程序在运行时动态获取类信息、创建对象、调用方法和访问属性,无需在编译时确定具体类。以下是核心应用场景:

1. 获取Class对象的三种方式
// 方式1:类名.class
Class<?> clazz1 = String.class;

// 方式2:对象.getClass()
String str = "Hello";
Class<?> clazz2 = str.getClass();

// 方式3:Class.forName()
Class<?> clazz3 = Class.forName("java.lang.String");

2. 动态创建对象
Class<?> clazz = Class.forName("com.example.User");
// 无参构造创建实例
Object obj1 = clazz.getDeclaredConstructor().newInstance();

// 带参构造创建实例
Constructor<?> constructor = clazz.getDeclaredConstructor(String.class, int.class);
Object obj2 = constructor.newInstance("Alice", 25);

3. 动态调用方法
// 获取方法对象
Method method = clazz.getDeclaredMethod("setName", String.class);

// 调用方法(需指定目标对象和参数)
method.invoke(obj2, "Bob");  // 相当于 obj2.setName("Bob")

// 调用静态方法
Method staticMethod = clazz.getDeclaredMethod("getCount");
staticMethod.invoke(null);  // 参数传null

4. 动态操作属性
// 获取字段对象(包括私有字段)
Field field = clazz.getDeclaredField("age");

// 解除私有字段访问限制
field.setAccessible(true);

// 读取属性值
int age = (int) field.get(obj2);  // 获取obj2的age值

// 设置属性值
field.set(obj2, 30);  // 修改obj2的age为30

5. 关键注意事项
  • 性能开销:反射操作比直接调用慢,频繁调用时需考虑性能优化
  • 安全限制:需处理IllegalAccessException等异常,私有成员需setAccessible(true)
  • 类型安全:强转类型时可能引发ClassCastException
  • 模块系统:Java 9+需在模块声明中开放权限(opens指令)
典型应用场景
  1. 框架设计(如Spring依赖注入)
  2. 动态代理(AOP实现)
  3. 序列化/反序列化工具
  4. 单元测试(Mock私有方法)
  5. 插件化系统开发

示例:完整调用链

Class<?> clazz = Class.forName("com.example.Employee");
Object emp = clazz.getDeclaredConstructor().newInstance();

// 设置属性
Field nameField = clazz.getDeclaredField("name");
nameField.setAccessible(true);
nameField.set(emp, "Lisa");

// 调用方法
Method displayMethod = clazz.getDeclaredMethod("displayInfo");
displayMethod.invoke(emp);  // 输出: Employee{name='Lisa'}

通过反射机制,Java程序获得了运行时动态操作类结构的能力,为框架开发和灵活编程提供了强大支持,但需谨慎处理性能和安全问题。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐