反射支持运行期动态操作类、方法和字段,实现解耦、通用映射、统一调用及私有成员访问,核心是通过class对象配合field、method、constructor完成。

反射能让你在运行时决定操作哪个类、调用哪个方法、访问哪些字段,而不是在写代码时就固定死。它不改变语法结构,但彻底改变了程序的组织逻辑——从“编译期绑定”转向“运行期决策”。关键在于用好 Class 对象这个入口,再配合 Field、Method、Constructor 的精准操作。
动态加载类,摆脱硬编码依赖
当业务需要根据配置或用户输入切换实现类(比如不同支付渠道、不同解析器),直接 new 某个具体类会把逻辑锁死。用 Class.forName() + 接口类型转换,就能让代码只依赖抽象,不依赖具体实现。
- 配置文件中写 payment.impl=AlipayProcessor 或 payment.impl=WechatProcessor
- 代码中通过 Class.forName(configValue).getDeclaredConstructor().newInstance() 创建实例
- 只要这些类都实现了同一接口(如 PaymentService),后续调用完全一致
通用对象赋值与映射,省去重复 setXXX 代码
处理数据库结果集、JSON 字段、表单参数时,如果每个实体类都手写字段映射,工作量大且易出错。反射可自动完成“字段名 → 属性名 → 值设置”的全过程。
- 遍历 ResultSet 的列名,用 clazz.getDeclaredField(columnName) 找到对应属性
- 调用 field.setAccessible(true) 突破 private 限制
- 用 field.set(obj, value) 完成赋值,一行代码适配所有实体类
- 配合注解(如 @Column)还能支持字段名与列名不一致的场景
统一方法调用入口,简化多态分支
传统方式处理不同对象的同名方法常要写一堆 instanceof 判断;反射能把“判断类型 + 获取方法 + 调用”压缩成一条链式逻辑。
- 传入任意对象和方法名字符串,如 invokeMethod(obj, "save")
- 内部用 obj.getClass().getMethod(methodName) 获取 Method 实例
- 再用 method.invoke(obj) 执行,无需关心 obj 是 User 还是 Order
- 还可扩展支持带参调用、返回值捕获、异常统一包装
绕过访问限制,支撑测试与调试能力
私有方法和字段通常无法被外部访问,但在单元测试、诊断工具或热更新场景中,恰恰需要临时“打开后门”。
- 用 clazz.getDeclaredMethod("doInternalCalc") 获取私有方法
- 调用 method.setAccessible(true) 关闭 JVM 访问检查
- 即可像调用公有方法一样执行,便于验证内部逻辑是否正确
- 注意:生产环境慎用,建议仅限测试类或受控工具模块
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











