
反射(Reflection)是 Java 在运行期间把"类、方法、字段、构造器"当成对象来操作的能力 。
一句话:通过 java.lang.reflect 包,代码可以 "照镜子"看清自己,还能动态改自己"。
Class<?> c = Class.forName("com.xxx.User"); // 加载类
Object o = c.getDeclaredConstructor().newInstance(); // 无参构造
Method m = c.getDeclaredMethod("setName", String.class);
m.setAccessible(true); // 破 private
m.invoke(o, "Lisa"); // 等价于 user.setName("Lisa")
二、优点(为什么离不开它)
-
运行时动态加载 ,写一次框架,跑所有类 →Spring IoC、MyBatis Mapper 都这么活。
-
解耦神器:编译期不需要知道具体类,类名配在 XML/注解即可。
-
打破封装:
setAccessible(true)能访问私有成员,做库级 hack(如深度拷贝、Mock)。 -
泛型擦除后仍能拿到参数化类型 →
new ArrayList<String>(){}.getClass().getGenericSuperclass()拿到String`。
硬编码就是指java每次运行都要经过固定的编译流程!
但是我们想要实现的事 原码不发生变化 但是运行结果发生变化的效果
所以这就需要 软编码 只修改字节码文件 .class后缀的文件
黑框子的部分可以随意的更改 比如按照前端传送过来的数据 或者是xml的配置 来修改 这就是软编码 通过反射机制实现 非常的灵活 可变 flexible

如果不想写死 需要市场的变化 动态的实现 反射机制就是很好的策略
Spring的对象管理就是采用反射机制管理的,MyBatis的自动映射数据也是通过反射机制来完成的。
所以反射不能实现业务开发上的一些代码,但是为我们的开发做了很多辅助的技术栈
三、缺点(生产环境痛点)
-
性能损耗:
反射调用要先做 访问检查 + 方法查找 + 装箱拆箱 ,比直接调用慢 10~20 倍;高频代码需缓存
MethodHandle或LambdaMetafactory才能用。 -
编译期安全检查失效:
方法名写错、参数传错,都要到运行时才抛
NoSuchMethodException/IllegalArgumentException。 -
破坏封装与不可变性:
私有字段被强制改掉,对象状态失控 → 多线程下更难排查。
-
代码可读性差:
"字符串"里写方法名,重构时 IDE 无法全局联动,容易遗漏。
-
版本升级脆弱:
内部私有 API 一旦改名,反射立即失效(JDK 9+ 模块系统后更严格,必须
--add-opens)。