揭秘Java反射:动态操控类的终极指南

在Java中,反射(Reflection)允许程序在运行时动态获取类的信息并操作类或对象。以下是反射的核心操作及示例:


1. 获取Class对象

反射的入口是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. 操作类成员

(1) 获取构造方法并创建对象
// 获取无参构造方法
Constructor<?> constructor = clazz1.getConstructor();
Object obj = constructor.newInstance(); // 等价于 new String()

// 获取带参构造方法(如String(byte[]))
Constructor<?> byteConstructor = clazz1.getConstructor(byte[].class);
Object byteStr = byteConstructor.newInstance(new byte[]{65, 66}); // "AB"
(2) 获取并调用方法
// 获取public方法(如String.length())
Method lengthMethod = clazz1.getMethod("length");
int len = (int) lengthMethod.invoke("ABC"); // 结果为3

// 获取private方法(需setAccessible(true))
Method privateMethod = clazz1.getDeclaredMethod("privateMethodName");
privateMethod.setAccessible(true);
privateMethod.invoke(obj);
(3) 访问字段
// 获取public字段(如String.value)
Field valueField = clazz1.getDeclaredField("value");
valueField.setAccessible(true);
char[] chars = (char[]) valueField.get("Java"); // 获取底层char数组

// 修改字段值
valueField.set("Java", new char[]{'K', 'o', 't', 'l', 'i', 'n'});

3. 动态代理(反射的高级应用)

通过ProxyInvocationHandler实现接口的动态代理:

interface Greeter { void greet(); }

InvocationHandler handler = (proxy, method, args) -> {
    System.out.println("Before greeting");
    return null; // 模拟方法调用
};

Greeter proxy = (Greeter) Proxy.newProxyInstance(
    Greeter.class.getClassLoader(),
    new Class[]{Greeter.class},
    handler
);
proxy.greet(); // 输出"Before greeting"

4. 反射的典型应用场景

  • 框架开发:如Spring的依赖注入、Hibernate的ORM映射。
  • 动态加载类:如插件化架构中加载未知类。
  • 测试工具:访问私有方法或字段进行单元测试。

注意事项

  1. 性能开销:反射比直接调用慢,频繁操作需缓存Class/Method对象。
  2. 安全限制:需处理SecurityException,且可能破坏封装性。
  3. 代码可读性:过度使用反射会降低代码可维护性。

通过反射,Java程序可以在运行时灵活地探索和操作类结构,但应权衡其带来的灵活性与潜在代价。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

代码的余温

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值