Java 9 中的 --add-exports 和 --add-opens 有啥区别?
Posted
技术标签:
【中文标题】Java 9 中的 --add-exports 和 --add-opens 有啥区别?【英文标题】:What's the difference between --add-exports and --add-opens in Java 9?Java 9 中的 --add-exports 和 --add-opens 有什么区别? 【发布时间】:2017-10-18 18:41:13 【问题描述】:由于新的模块系统,Java 9 (jdk-9+170) 默认情况下不允许应用程序查看 JDK 中的所有类,这与所有以前的 Java 版本不同。
为了解决这个问题,java
命令行提供了一个新参数--add-exports
,它允许打破封装,如下所示:
java -jar josm.jar --add-exports java.base/sun.security.util=ALL-UNNAMED --add-exports java.base/sun.security.x509=ALL-UNNAMED
JEP 261 对此进行了很好的解释。
我已经阅读了使用相同语法的类似选项--add-opens
,但尚未更新 JEP 261 来描述它(最后更新:2017/03/08 13:58)。
这两个选项有什么区别?
编辑:JEP 261 已于 2017-09-22 更新以解释它。
【问题讨论】:
【参考方案1】: 使用--add-exports
导出包,这意味着其中的所有公共类型和成员都可以在编译和运行时访问。
使用--add-opens
打开包,这意味着其中的所有类型和成员(不仅是公共的!)都可以在运行时访问。
所以在运行时的主要区别是--add-opens
允许“深度反射”,即非公共成员的访问。您通常可以通过调用setAccessible(true)
的反射代码来识别这种访问。
【讨论】:
值得补充的是,在运行时-add-opens
暗示-add-exports
这两个项目符号描述了--add-opens
可以访问的类型/成员是--add-exports
的超集,所以我不认为说一个暗示另一个会给描述增加任何价值。
现在在 JEP 261 中解释了这一点,因为 Mark 今天更新了页面:openjdk.java.net/jeps/261
查找哪个模块提供哪个包的命令:java --list-modules | tr @ " " | awk ' print $1 ' | xargs -n1 java -d
模块的名称将显示为带有@,而没有它的包的名称
--add-opens
只关心反射,这是一个运行时概念,因此该标志不适用于编译器。以上是关于Java 9 中的 --add-exports 和 --add-opens 有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章
Java 9 中的 Maven 更新,Eclipse 中的 Java 8 中的 Maven 编译
Java 9 hdpi 显示支持 - 多分辨率图像 - Windows 中的命名约定和加载