1.模块化解决的问题
可靠的配置
模块必须声明对其他模块的显式依赖。 模块系统验证程序开发的所有阶段的依赖关系—编译时,链接时和运行时。
强封装
模块必须明确声明其中哪些公共类型可以被其他模块访问。Java 9中的公共类型并不意味着程序的所有部分都可以访问它。
模块化JDK/JRE
使用jlink(JDK9的jlink工具)创建应用程序的自定义运行时映像,其中仅包含应用程序中使用的模块。
2.java平台的模块
标准模块
以Java 为前缀。比如java.base,java.sql。
非标准模块
以jdk为前缀。 比如jdk.charsets,jdk.compiler。
基础模块
模块系统默认只知道基础模块java.base,需通过模块指定的依赖关系发现其他模块。
3.模块的依赖关系
原则
模块需明确声明公共类型可供其他模块使用,且使用公共类型的模块需明确声明对公共模块的依赖。
模块中的所有未导出的软件包都是模块的私有的,不能在模块之外使用。
在模块系统的上下文中,使用三个术语 —— 需要(require),读取(read)和依赖(depend)。
开放模块
标注open/opens的模块/包,外部模块可使用反射访问公共和私有API。
3.1.模块图
所有其他模块都隐含地依赖于java.base模块。应用程序的模块化结构可以被视为一个称为模块图。
java.se的平台模块的模块图
4.聚合模块
创建一个不包含任何代码的模块,它收集并重新导出其他模块的内容, 这样的模块称为聚合模块。
Java 9包含几个聚合模块,如java.se和java.se.ee。
- java.se模块收集Java SE的不与Java EE重叠的部分。
- java.se.ee模块收集组成Java SE的所有模块,包括与Java EE重叠的模块。
5.声明模块
语法
[open](可选)声明开放的模块。 一个开放的模块导出所有的包,以便其他模块使用反射访问。
<module>是要定义的模块的名称。
<module-statement>是模块语句。 模块声明中可以包含零个或多个模块语句。包含五种类型:
- 导出语句(exports statement):控制对模块代码的访问;
- 开放语句(opens statement):控制对模块代码的访问;
- 需要语句(requires statement):声明模块对另一个模块的依赖关系;
- 使用语句(uses statement):提供特定服务接口;
- 提供语句(provides statement):提供特定服务实现。
模块命名
- 模块名称可以是Java限定标识符。 合法标识符是一个或多个由点分隔的标识符。
- 与包命名约定类似,模块名称需唯一。
访问控制
- 导出语句表示允许在编译时和运行时访问指定包的public成员。
exports <package>; exports <package> to <module1>, <module2>...;
- 开放语句表示允许在运行使用反射访问其public及private成员。
opens <package>; opens <package> to <module1>, <module2>...;
声明依赖
- 需要语句声明当前模块与另一个模块的依赖关系。
requires <module>; requires transitive <module>; requires static <module>; requires transitive static <module>;
static:编译时的依赖是强制的,但在运行时是可选的
transitive修饰符会导致依赖于当前模块的其他模块具有隐式依赖性。
配置服务
- Java使用服务提供者和服务使用者分离的服务提供者机制。使用语句(uses statement)和提供语句(provides statement)实现其服务。使用语句可指定服务接口名字,当前模块就会发现它,使用ServiceLoader类进行加载。
uses <service-interface>;
provides <service-interface> with <service-impl-class1>, <service-impl-class2>...;
6. 模块描述符
模块声明
模块声明module-info.java,该文件存储在该模块的源文件层次结构的根目录下。
模块版本
模块打包到JAR时,提供了一个添加模块版本的选项,将其添加到module-info.class文件中。
打包模块
- 目录;
- 模块化的JAR文件;
模块化JAR可在jdk9之前的版本使用。在之前版本,模块声明文件将被忽略。
- JMOD文件,它是JDK 9中引入的一种新的模块封装格式。
JMOD文件使用.jmod扩展名。 JDK模块被编译成JMOD格式,放在JDK_HOME jmods目录中。在编译时和链接时支持JMOD 文件,在运行时不支持。