繁体   English   中英

Java 17反射问题

[英]Java 17 Reflection issue

尝试调用此 function 以设置私有 static 最终值。 此反射代码适用于 Java 11,但不适用于 17。遇到 no such filed 异常错误。

    public static void setFinalStatic(Field field, Object newValue) throws Exception {
        field.setAccessible(true);
        Field modifiersField = Field.class.getDeclaredField("modifiers");
        modifiersField.setAccessible(true);
        modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
        field.set(null, newValue);
    }
java.lang.NoSuchFieldException: modifiers
    at java.base/java.lang.Class.getDeclaredField(Class.java:2610)

我确实尝试了 --add-opens java.base/java.lang.reflect=ALL-UNNAMED,但没有用。

任何解决方案或解决这个问题?

Java9 中断了反射,随着版本号的增加,中断变得更糟。 本质上,在启动 java 可执行文件时,如果不添加一堆复杂的--add-opens行,访问其他模块(java 9 中引入的模块)的非导出元素将无法工作。 “模块”作为一个概念在 java9 之前并不存在,因此,java8 及以下的 javadoc 没有提及任何这一点。

绝大多数应用程序和库警告说它们不能在较新的 JVM 上运行,这是因为对 JVM 的这种向后不兼容的更改。

解决方案是以下四种选择之一:

  1. 通常的一种:降级到 JDK8 或 11。
  2. --add-opens舞蹈。
  3. 使用例如Unsafe做一些简单的 hackery。 仅适用于高级用户,请注意,这可能意味着不久的将来 JVM 版本将再次中断。
  4. 找出一种方法来做到这一点,而不必将您的方式反映到其他模块的非导出部分。 在这里,具体来说.. 只需调用field.getModifiers()

对于这个问题,从版本 12 开始就不可能再直接了。

对于 java 17,我使用了以下解决方法:

    public static void setFinalStatic(Field field, Object newValue) throws Exception {
        field.setAccessible(true);
        Method getDeclaredFields0 = Class.class.getDeclaredMethod("getDeclaredFields0", boolean.class);
        getDeclaredFields0.setAccessible(true);
        Field[] fields = (Field[]) getDeclaredFields0.invoke(Field.class, false);
        Field modifiersField = null;
        for (Field each : fields) {
            if ("modifiers".equals(each.getName())) {
                modifiersField = each;
                break;
            }
        }
        modifiersField.setAccessible(true);
        modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
        field.set(null, newValue);
    }

要运行,您应该添加这些 arguments:

--add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.lang.reflect=ALL-UNNAMED

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM