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