【发布时间】:2018-05-12 12:11:01
【问题描述】:
我正在使用新的模块化系统,但遇到了反射问题。
在我的代码中,我尝试通过反射调用 Map.Entry 的 getValue 方法。它不允许我这样做。
我已经阅读了一些关于新模块化系统的教程,为什么要设置反射保护,什么是导出和打开,如何以及在哪里声明它们等等。 但是对于这个特定的人,我不确定是否了解所有内容。
这是我能提供的最少代码:
package pkg;
import java.util.*;
import java.lang.reflect.*;
public class Test {
public static void main (String[] args) throws Exception {
Map<String,Object> someMap = new LinkedHashMap<>();
someMap.put("someKey", "someValue");
Map.Entry<String,Object> entry = someMap.entrySet().iterator().next();
System.out.println(entry.getValue()); // normal access is fine
Method getter = entry .getClass() .getMethod("getValue");
getter.setAccessible(true); //1
System.out.println(getter.invoke(entry)); //2
}}
调用 setAccessible 时,它会崩溃 (1) :Exception in thread "main" java.lang.reflect.InaccessibleObjectException: Unable to make public final java.lang.Object java.util.HashMap$Node.getValue() accessible: module java.base does not "opens java.util" to module mymodule
注释setAccessible(1)时,调用invoke(2)时崩溃:Exception in thread "main" java.lang.IllegalAccessException: class pkg.Test (in module mymodule) cannot access a member of class java.util.HashMap$Node (in module java.base) with modifiers "public final"
幸运的是,错误消息非常明确:我可以通过使用命令行参数--add-opens java.base/java.util=mymodule 添加缺少的打开来解决问题。
但这可能不是长期的正确方法。
我在某处读到 --add-opens/exports 无论如何都会随着 Java 11 消失。
难道没有比使用 --add-opens 更好的解决方案吗?
正常/直接/常规访问有效,getValue 方法是公共的,Map.Entry 显然是从 java.base 正确导出的。 那么为什么这个反射调用被阻塞了呢?
感谢您的回答。
【问题讨论】:
标签: java