本帖最后由 结冰的离季 于 2022-5-10 12:58 编辑 
要求是修改对象的private final 修饰的成员变量
但是从 java 17 开始
官方强制 封装 JDK 内部类 的改动之后就G了 https://openjdk.java.net/jeps/403
我的代码是
复制代码getDeclaredField("modifiers") 就  NoSuchFieldException 了
咋办,在线等
解决方案
复制代码
要求是修改对象的private final 修饰的成员变量
但是从 java 17 开始
官方强制 封装 JDK 内部类 的改动之后就G了 https://openjdk.java.net/jeps/403
JEP 396 moved from default of relaxed strong encapsulation to a default of strong encapsulation, but JDK 9 through 16 is possible to relax it. With JDK 17, the use of the launcher option is no longer possible.
Code that uses reflection to access private fields of exported java.* APIs will no longer work. For example,
var ks = java.security.KeyStore.getInstance("jceks");
var f = ks.getClass().getDeclaredField("keyStoreSpi");
f.setAccessible(true);
will fail with an exception of the form
Exception in thread "main" java.lang.reflect.InaccessibleObjectException:
Unable to make field private java.security.KeyStoreSpi
java.security.KeyStore.keyStoreSpi accessible: module java.base does
not "opens java.security" to unnamed module @6e2c634b
我的代码是
- Field field = spm.getClass().getDeclaredField("fileAssociations");
 
-                         field.setAccessible(true);
 
-                         Field modifiersField = Field.class.getDeclaredField("modifiers");
 
-                         modifiersField.setAccessible(true);
 
- modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
咋办,在线等
解决方案
- public void test() {
 
-         try {
 
-             Field field = Bukkit.getServer().getClass().getDeclaredField("commandMap");
 
-             field.setAccessible(true);
 
-             SimpleCommandMap map = (SimpleCommandMap) field.get(Bukkit.getServer());
 
-             Field f = Unsafe.class.getDeclaredField("theUnsafe");
 
-             f.setAccessible(true);
 
-             Unsafe unsafe = (Unsafe) f.get(null);
 
-             long offset = unsafe.objectFieldOffset(field);
 
-             //map为替换的对象
 
-             unsafe.putObject(Bukkit.getServer(), offset, map);
 
-         } catch (Exception e) {
 
-             e.printStackTrace();
 
-         }
 
- }
你不能修改一个 static final 的字段,因为 static final 字段是一个强力的语义,JVM 会积极地内联这些字段。
对于 static final 字段的修改对于代码是(很有可能)不可见的。
对于 static final 字段的修改对于代码是(很有可能)不可见的。