java - 为什么要从 Java 模块打开一个不存在的包?

标签 java java-module jls

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 BatemanMichael 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 文件的构建脚本:

  1. 它编译.java文件(我们有module-info.java定义opens com.foo.abc;com/foo/abc 目录(“包”)不存在)
  2. 它创建com/foo/abc 目录
  3. 它复制 config_dev.properties 文件,在这一步决定我们构建的环境(PROD/TEST/DEV)
  4. JAR文件打包,包含字节码和资源。

如果不允许为不存在的目录打开,则第 1 步将失败。但它只在编译时给出警告,这没关系。

关于java - 为什么要从 Java 模块打开一个不存在的包?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56147221/

相关文章:

java - Android Firebase - 无法从 Firebase 快照接收正确的 JSON

java - 如何使用 `javac` 指令编译 `exports... to` 模块而不出现任何警告?

java - Java中 "final class"有什么意义?

Java RegEx - 如何将每个 Stringchar 转换为 *?

java - Java 9 中创建了多少个未命名的模块?

java - 编译 fatal error : Failed to run the ecj compiler: Unrecognized option : --module-version

Java "fresh type variable"

java - 如何创建已知类型的类文字: Class<List<String>>

java - Java 外来标识符的状态

java - 如何在 OpenGL ES 中移动带有纹理的形状?