什么是反射
想象你走进一个神秘房间,房间里摆满了上锁的宝箱。正常情况下你需要对应的钥匙才能打开每个箱子,但突然你获得了一个万能开锁器,这个“万能开锁器”就类似于是Java反射!
反射允许你在程序运行时动态地获取类的信息(如方法、字段等),甚至可以调用这些方法或访问这些字段,即使它们被声明为private
。这意味着你可以像拥有X光视力一样,“透视”任何对象的内部构造,并根据需要调整或操作它们。
🔍 反射的主要能力:
- 透视任意类的内部结构:就像使用X光扫描一样,可以查看类的所有成员。
- 访问私有方法:突破
private
关键字的限制,调用和修改私有方法。 - 动态创建对象:无需使用
new
关键字即可实例化对象。 - 实时修改对象属性:无视
final
关键字,动态修改对象的属性值。
反射的应用场景
Java反射在许多场景中都有广泛的应用,主要包括以下方面:
- 最常见的是搭配注解使用,获取运行时的方法参数、注解值。在许多框架中有对应的示例,比如Spring的
@Autowired
注解;// Spring内部通过反射实现的依赖注入 Field[] fields = bean.getClass().getDeclaredFields(); for (Field field : fields) { if (field.isAnnotationPresent(Autowired.class)) { Object dependency = context.getBean(field.getType()); field.setAccessible(true); field.set(bean, dependency); } }
- 动态代理也是基于反射来实现的。在运行时生成代理类,通过反射,可以动态地创建代理类,并在运行时将方法调用转发给目标对象;
// 动态代理示例 Object proxy = Proxy.newProxyInstance( target.getClass().getClassLoader(), target.getClass().getInterfaces(), (proxy, method, args) -> { System.out.println("【前置通知】"); return method.invoke(target, args); } );
反射使用建议
虽然反射提供了极大的灵活性,但它并非没有代价,频繁地使用反射可能会导致程序性能下降:
- 安全检查费时:每次反射调用都要验证访问权限。
- 编译器优化失效:无法享受方法内联等优化。
- 资源占用倍增:需要额外维护方法/字段的元数据。
✅反射推荐场景:
- 框架开发(如Spring、MyBatis)
- 动态插件系统
- 通用工具类开发
❌ 反射慎用场景:
- 高频调用的业务代码
- 对性能敏感的实时系统
- 安全性要求极高的金融系统
✨ 反射就像程序员手中的量子纠缠装置,让代码能够突破时空限制与运行时环境对话。记住:能力越大,责任也越大