java - 一个Java模块可以导出一个包,该包的名称是另一个模块中包的子包吗?

标签 java java-9 java-module java-platform-module-system java-package

所以我知道,在Java 9模块(Project Jigsaw)中,不允许拆分包。也就是说,以下模块不能既导出同名的包,又不能在运行时同时使用:

模块 1

module com.example.foo {
    exports com.example.foo;
}

模块 2

module com.example.foo {
    exports com.example.foo;
}

不允许(或者,至少,它们不能同时运行)。但我不清楚的是子包是如何发挥作用的。如果一个模块导出包com.example.foo ,可以另外打包导出com.example.foo.bar ?例如,我想做以下事情:

模块 1

module com.example.foo {
    exports com.example.foo;
    exports com.example.foo.exceptions;
    exports com.example.foo.util;
}

模块 2

module com.example.foo.impl1 {
    requires com.example.foo;
    exports com.example.foo.impl1;
}

模块3

module com.example.foo.impl2 {
    requires com.example.foo;
    exports com.example.foo.impl2;
}

这是允许的吗?所有三个模块能够在运行时一起使用吗?或者模块 com.example.foo 的事实是否如此?导出com.example.foo阻止另一个模块 ( com.example.foo.impl1 ) 导出具有子包名称 ( com.example.foo.impl1 ) 的包?

最佳答案

根据 @RoddyoftheFrozenPeas 的建议,我创建了一个多模块示例项目来演示此处的行为。 tl;dr 是它有效!你确实可以这样做。为了证明我也正确使用了模块,我尝试了我知道行不通的第一件事,而且我确实遇到了阻止它运行的错误。

我创建了this GitHub gist ,您可以在其中看到完整的源代码(我永远不会删除它),其中显示了我如何设置该项目。 gist 文件名中的下划线表示目录(不能使用斜杠)。该项目布局如下:

- root
  - com-example-foo
    - src
      - module-info.java
      - com
        - example
          - foo
            - SalutationProvider.java
  - com-example-foo-impl1
    - src
      - module-info.java
      - com
        - example
          - foo
            - implone
              - StandardOutHelloer.java
  - com-example-foo-impl2
    - src
      - module-info.java
      - com
        - example
          - foo
            - impltwo
              - StandardErrHelloer.java

它编译得很好,然后这是运行它的结果:

$ java -Dfile.encoding=UTF-8 -p out/production/com-example-foo-impl1:out/production/com-example-foo -m com.example.foo.implone/com.example.foo.implone.StandardOutHelloer
Hello, World!

$ echo $?
0

$ java -Dfile.encoding=UTF-8 -p out/production/com-example-foo-impl2:out/production/com-example-foo -m com.example.foo.impltwo/com.example.foo.impltwo.StandardErrHelloer
Hello, World!

$ echo $?
15

我相信这应该是链接的重复问题的答案,因为现有的答案只是说“不存在子包之类的东西”,而没有提供任何工作示例或文档来表明这是明确允许的。但是,由于链接的重复问题本身被标记为有关子包的不相关问题的重复项,因此我无法在那里发布此答案(这是一个封闭的问题)。因此,我将其发布在这里。

关于java - 一个Java模块可以导出一个包,该包的名称是另一个模块中包的子包吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54370999/

相关文章:

java - 如何将模块声明注入(inject) JAR?

java - 使用 EventKey 在 EditText 上设置文本

java - Android中如何访问Activity对象

java.text.ParseException : Unparseable date: "04-02-2019"

maven - 从 maven-antrun-plugin 运行的 Ant 在 Java 9 上找不到脚本引擎

Java 9 模块系统

java - 如何获取调用DocumentFilter的对象

java - Java9及更高版本中线程间通信无法正常工作

java - 包与 Java 9 中的自动模块冲突

java - Java 9 中文件夹/目录名称为模块名称是否存在问题?