本条基于 Java 17(Minecraft 1.20.1 所用版本)。
Reflection(反射,java.lang.reflect)是在运行时获取类、字段、方法、构造器的信息并调用它们的机制。
常用 API
Class.forName、getDeclaredField、getDeclaredMethod、getDeclaredConstructorField.get/Field.set、Method.invoke、Constructor.newInstancesetAccessible(true):关闭访问检查,访问 private 成员
模块系统下的限制
- Java 16 起默认强封装,Java 17 彻底强封装:对未开放(opens)的包调用
setAccessible(true)会抛InaccessibleObjectException。 - 可用
--add-opens启动参数放开,或借助 Unsafe、MethodHandle 中的IMPL_LOOKUP绕过。 static final字段即使setAccessible(true)也不能用Field.set修改;Java 12 起Field的modifiers等字段被反射过滤,旧的“去掉 final 修饰符”写法失效。
在模组中
- Forge 1.20.1 生产环境使用 SRG 名,反射时要写 SRG 名,或使用
ObfuscationReflectionHelper自动映射。 - 反射调用有额外开销,热点代码可改用 MethodHandle。
- 例如通过反射取得 ServerLevel 的
entityTickList,即可直接操作 EntityTickList。