我是 Java 9 的新手,正在观看 YouTube 上 Java 的模块化视频讲座。 他们提到了模块化的 3 个好处 -
据我对拆分包的理解,假设一个应用程序依赖于多个依赖项,并且假设包
abc.pqr.xyz
存在于超过 1 个 jar 中。
那么有可能该包中的某些类将使用 jar1 中的类,而其他类将使用 jar2 中的类。
这可能会导致运行时出现一些难以调试的问题。
视频说模块化解决了这个问题。 但这就是我想要理解的?
假设 test.module1 具有以下模块信息:
module test.module1{
exports abc.pqr.xyz;
}
另一个模块2,具有以下模块信息:
module test.module2{
exports abc.pqr.xyz;
}
现在假设在我的应用程序中我添加了这两个模块的依赖项:
module test.myapp{
requires test.module1;
requires test.module2;
}
现在我又有了 2 个模块依赖项,其中某些类可能会出现在这两个模块中。 那么在运行时如何解析从哪个模块获取类定义呢?
Java 9 如何避免拆分包问题?
根据问题中描述的场景,您将开始面临错误阅读:
模块
从test.myapp
和test.module1
读取包test.module2
模块的可读性来自模块系统的状态详细阐述了模块的使用,如下所示,您的用例将会感兴趣(重点是我的):
模块图中定义的可读性关系是基础 可靠配置:模块系统确保
- 每一个依赖关系都由另一个模块来实现
- 模块图是非循环的
- 每个模块最多读取一个定义给定包的模块
- 并且定义同名包的模块不会互相干扰。
在模块系统中暗示相同的好处也很详细
也就是说,当前实施的解决方案是可靠的配置不仅仅是更可靠; 也可以 更快。当模块中的代码引用包中的类型时 包保证在该模块中或在 正是该模块读取的模块之一。
寻找时 特定类型的定义存在,因此无需搜索 在多个模块中,或者更糟糕的是,在整个类路径中。
test.module1
和
test.module2
是显式模块,您可以选择在其中之一中实现包
abc.pqr.xyz
或者您将其从两者中拉出到您自己的单独模块test.mergeModule
中,此后可以将其用作跨客户端的独立模块。
,您可以利用扩展到类路径的桥,让此类jar保留在类路径上并被视为未命名模块,默认情况下导出其所有包。同时,任何自动模块在读取其他每个命名模块时也会读取未命名模块。 再次引用文档并举例说明,以便您可以关联到您的问题:
如果显式模块 com.foo.app 中的代码引用了公共类型
com.foo.bar
,例如,该类型的签名指的是 JAR 文件之一仍在类路径上,然后是代码
将无法访问该类型,因为com.foo.app
不能依赖未命名的模块。com.foo.app
可以通过将com.foo.app
暂时视为自动模块来解决此问题,以便其 代码可以从类路径访问类型,直到 类路径上的相关 JAR 文件可以被视为自动 模块或转换为显式模块。
test.myapp
的模块路径中遇到两个模块时,JVM 将抛出一个错误,指示
test.module1
和 test.module2
正在尝试导出相同的包。