JLS 11 "7.7.2. Exported and Opened Packages"说:
It is permitted for
opens
to specify a package which is not declared by a compilation unit associated with the current module.
这会是什么场景?为什么需要这个?
最佳答案
感谢 Alan Bateman 和 Michael Easter 的解释,我能想到一些现实的场景。
首先,正如 Alan 和 Michael 所解释的:JLS 允许“打开”没有 Java 类型的目录,以应对我们在其中保留资源的情况。所以,对我们来说,这些是“资源目录”,但 JLS 将其命名为 package which is not declared by a compilation unit
。这甚至不是“允许”的问题,而是“必须”的问题。如果没有针对资源目录 (com/foo/abc
) 的 opens
指令,另一个模块将无法读取这样的资源:
InputStream is = ClassLoader.getSystemResourceAsStream("com/foo/abc/config.properties");
其次,我写这个问题主要是因为我对 opens
允许指定甚至不存在的“包”(目录)感到困惑,尽管它会发出警告,但编译成功。
一个可能的场景,我可以想到模块化 JAR 文件的构建脚本:
- 它编译
.java
文件(我们有module-info.java
定义opens com.foo.abc;
和com/foo/abc
目录(“包”)不存在) - 它创建
com/foo/abc
目录 - 它复制
config_dev.properties
文件,在这一步决定我们构建的环境(PROD/TEST/DEV) - JAR文件打包,包含字节码和资源。
如果不允许为不存在的目录打开
,则第 1 步将失败。但它只在编译时给出警告,这没关系。
关于java - 为什么要从 Java 模块打开一个不存在的包?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56147221/