计算机系统应用教程网站

网站首页 > 技术文章 正文

Java 9揭秘-模块依赖(三) java 9

btikc 2024-10-18 04:40:18 技术文章 7 ℃ 0 评论

隐含依赖(Implicit Readability)

如果一个模块A依赖另一个模块B,而另一个模块B依赖于模块C,这样模块A就隐含依赖于C。 每个模块都隐含依赖java.base模块。 隐含依赖不限于java.base模块。 模块也可以隐含依赖另一个模块,而不是java.base模块。 在展示如何向模块添加隐含之前,先构建一个示例,看看为什么我们需要这个功能。

在上一节中,创建了两个名为com.jdojo.address和com.jdojo.person的模块,其中第二个模块使用以下声明读取第一个模块:

module com.jdojo.person {
 requires com.jdojo.address;
 
}

com.jdojo.person模块中的Person类引用com.jdojo.address模块中的Address类。 让我们创建另一个名为com.jdojo.person.test的模块,它读取com.jdojo.person模块。 模块声明如下所示。

module com.jdojo.person.test {

requires com.jdojo.person;

}

需要将com.jdojo.person项目添加到com.jdojo.person.test项目的模块路径。 否则,编译代码将产生错误。

然后,在com.jdojo.person.test项目中添加主类。

package com.jdojo.person.test;
import com.jdojo.person.Person;
public class Main { 
 public static void main(String[] args) {
 Person john = new Person(1001, "John", "Jacobs"); // Get John's city and print it
 String city = john.getAddress().getCity();
 System.out.printf("John lives in %s%n", city);
 }
}

上面的代码会出现以下错误信息:

E:\Java\com.jdojo.person.test\src\com\jdojo\person\test\Main.java:16: 错误: 无法访问Address

String city = john.getAddress().getCity();

找不到com.jdojo.address.Address的类文件

错误原因在于com.jdojo.person.test模块不能访问Address类。 Address类在com.jdojo.address模块中,com.jdojo.person.test模块没有访问模块。 看代码,似乎很明显代码应该编译成功。 既然可以使用Person类; 所以就应该可以使用Address类。 这里,john.getAddress()方法返回一个无权访问的Address类型的对象。 模块系统只是对com.jdojo.address模块定义进行了封装。 如果模块想要明确或者隐式地使用Address类,它必须读取com.jdojo.address模块。 如何解决? 简单的答案是com.jdojo.person.test模块通过将其声明模块来读取com.jdojo.address模块。

// module-info.javamodule com.jdojo.person.test {
 requires com.jdojo.person;
 requires com.jdojo.address;
}

上面的模块定义会收到另一个错误,该错误将声明未找到com.jdojo.address模块。 将com.jdojo.address项目添加到com.jdojo.person.test项目的模块路径来修复此错误。 模块路径设置如下所示。

此时,显示了com.jdojo.person.test模块的模块图。

在com.jdojo.person.test模块中编译并运行Main类。 它将打印以下内容:

到目前为止,我们通过添加requires语句解决了问题,但是其他使用Person类的的模块同样需要添加requires语句,这种语句是非常臃肿的。Java9的设计师意识到这个问题并且提供了一个简单的方法解决这个问题。目前,你所有需要做的改变就是给com.jdojo.person的模块定义语句中的requires添加一个transitive表示,表示对com.jdojo.address的传递依赖。

module com.jdojo.person {

requires transitive com.jdojo.address;

exports com.jdojo.person;

}

现在我们可以从移除requires com.jdojo.address;这个语句,重新编译结果完全正确。

从模块图中发现,这样实现了传递依赖。

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表