在此章节中,主要学习以下内容:
如何声明模块依赖
模块的隐式可读性意味着什么以及如何声明它
限定导出(exports)与非限定导出之间的差异
如何定义可选的运行时依赖
如何打开整个模块或其选定的软件包进行深层反射
JDK 9中的访问类型
跨模块分割包
模块声明的约束
不同类型的模块:命名,未命名,显式,自动,普通和开放的模块
如何使用 javap 工具来解析模块的定义
一. 声明模块依赖
如果一个模块需要使用另一个模块中的公共类,第二个模块需要导出包含公共类型的包同时第一个模块需要读取第二个模块。注意,两个模块之间的依赖声明是不对称的,提供类的模块对外导出的是 包 ( package ),然而使用类的模块读取的是 模块 (module)。
假设你现在已经有两个模块,分别是:
com.jdojo. address :包含Address类
com.jdojo.person:包含Person类。
其中,com.jdojo.person模块想使用com.jdojo.address模块下的Address类,其模块图如下所示:
在 NetBeans 中,可以创建两个名为com.jdojo.address和com.jdojo.person的Java项目。 每个项目将包含与项目名称相同的模块的代码。下面包含了com.jdojo.address的模块声明和Address类的代码。
package com.jdojo.address;
public class Address {
private String line1 = “1111 Main Blvd.”;
private String city = “Jacksonville”;
private String state = “FL”;
private String zip = “32256”;
public Address() {
}
public Address(String line1, String line2, String city,
String state, String zip) {
this.line1 = line1;
this.city = city;
this.state = state;
this.zip = zip;
}
public String getZip() {
return zip;
}
public void setLine1(String line1) {
this.line1 = line1;
}
public void setCity(String city) {
this.city = city;
}
public void setState(String state) {
this.state = state;
}
public void setZip(String zip) {
this.zip = zip;
}
public String getLine1() {
return line1;
}
public String getCity() {
return city;
}
public String getState() {
return state;
}
@ Override
public String toString() {
return “[Line1:” + line1 + “, State:” + state
+ “, City:” + city + “, ZIP:” + zip + “]”;
}
}
exports 语句用于将包导出到所有其他模块或某些命名模块。 被导出包中的所有公共类都可以在编译时和运行时访问。 在运行时,可以使用反射来访问公共类的公共成员。 公共类的非公开成员无法使用反射进行访问,即使这些成员上使用了setAccessible(true)方法。
exports语句的一般语法如下所示:
exports <package>;
该语句将<package>中的所有公共类型导出到所有其他模块。 也就是说,读取此模块的任何模块都将能够使用<package>中的所有公共类型。
com.jdojo.address模块导出com.jdojo.address包,因此Address类可以由其他模块使用,它是公共的,也可以在com.jdojo.address包中使用。所以可以在com.jdojo.person模块中使用Address类。
下列包含com.jdojo.person模块的模块声明和Person类的代码。
module com.jdojo.person {
requires com.jdojo.address;
exports com.jdojo.person;
}
package com.jdojo.person;
import com.jdojo.address.Address;
public class Person {
private long personId;
private String firstName;
private String lastName;
private Address address = new Address();
public Person(long personId, String firstName, String lastName) {
this.personId = personId;
this.firstName = firstName;
this.lastName = lastName;
}
public long getPersonId() {
return personId;
}
public void setPersonId(long personId) {
this.personId = personId;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
@Override
public String toString() {
return “[Person Id:” + personId + “, First Name:” + firstName
+ “, Last Name:” + lastName + “, Address:” + address + “]”;
}
}