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 中的命名约定和加载

Java 9 - 发布者和订阅者如何工作

Java 9 的版本字符串方案中的第 4 个数字是啥意思?

Java定义数组+2,33,23,44,5,88,9,2,去掉数组中的最大值和最小值,剩?

Java 9 中的 9 个新特性