Java 9:不需要“打开”模块以通过反射进行访问?
Java模块逻辑中的opens
关键字允许反射访问(here)。我最近移植了一个复杂的JavaFX应用程序。Java15取得了成功,但这是一场噩梦,因为JavaFX正确地基于反射访问
我的问题是关于一个更简单的Java 15应用程序的,它可以完美地运行,但是我预期会出现一个运行时错误,而不会发生!为什么?任何亮点欢迎。。。因此,我在两个模块之间有一个非常常见的客户机/服务器关系,如下所示:
module PauWare2 {
exports com.pauware.pauware_engine.Core;
}
module My_device_module {
requires PauWare2;
}
人们可能会注意到opens
在My_device_module
中没有使用。实际上,PauWare2
通过反射访问公共方法:
package My_device_package;
public class My_device { // In 'My_device_module'
public void a() {}
com.pauware.pauware_engine.Core.AbstractStateMachine _My_device_state_machine;
// Reflective access of 'a' method by '_My_device_state_machine':
_My_device_state_machine.launchByReflection(this, "a");
}
我预期会出现运行时错误,它涉及opens My_device_package to PauWare2;
中的My_device_module
?然而,如前所述,一点问题都没有。。。你知道吗?提前谢谢
# 1 楼答案
与Java语言规范相比:
所以
opens
指令的重点是而不是它授予反射访问权,exports
也这样做。使用opens
而不是exports
的目的不是授予编译时访问权,这意味着运行时只有反射访问权是可能的因此,无论如何导出包时,不需要额外的
opens
。这意味着,如果你可以直接访问某个东西,你也可以反射地访问它或者,按照规范的字面意思,不是通过编译标准Java源代码生成的类文件可以在运行时访问打开的类型和成员
你链接的这篇文章是关于“深度反思”的,通过调用^{} 可以访问某个成员。但就连引用的文件也说:
因此,第二个项目符号清楚地表明,对于导出包的
public
类型的public
成员,也可以使用setAccessible(true)
相关差异将在下一节中介绍:
因此,它只会对非
public
成员产生影响,尤其是private
和默认(包)访问