4.JDK默认模块有哪些?
Java 9的一个关键方面是将JDK划分为模块以支持各种配置。 (请参阅“ JEP 200:模块化JDK”。表1中显示了所有Java模块化JEP和JSR。)将JDK的bin文件夹中的java命令与--list-modules选项一起使用,如下所示:
列出了JDK的模块集,其中包括实现Java语言SE规范的标准模块(以Java开头的名称),JavaFX模块(以Javafx开头的名称),特定于JDK的模块(以jdk开头的名称)和特定于Oracle的模块 (名称以oracle开头)。 每个模块名称后跟一个版本字符串-@ 9表示该模块属于Java 9。
5.如何声明一个模块?
如前所述,模块必须提供模块描述符-元数据,用于指定模块的依赖关系,该模块可用于其他模块的软件包等等。 模块描述符是模块声明的编译版本,是在名为module-info.java的文件中定义的。 每个模块声明都以关键字module开头,后跟一个唯一的模块名称和一个用大括号括起来的模块主体,如:
在项目classpath 根目录下,创建文件 module-info.java ,文件名必须是 module-info.java,内容如下,即可声明一个模块
}
模块声明的主体可以为空,也可以包含各种模块指令,包括需求,导出,提供,使用,使用和打开(我们将讨论每一个)。 稍后您将看到,编译模块声明会创建模块描述符,该描述符存储在模块根文件夹中名为module-info.class的文件中。 在这里,我们简要介绍每个模块指令。 之后,我们将介绍实际的模块声明。
稍后将介绍的关键字 exports,module,open,open,provid,require,use,with,to和transitive是限制性关键字。 它们只是模块声明中的关键字,可以在代码中的其他任何地方用作标识符。
6.模块声明关键字
requires:
模块指令指定该模块依赖于另一个模块,这种关系称为模块依赖关系。每个模块必须明确声明其依赖性。当模块A需要模块B时,可以说模块A读取模块B,模块B读取模块B。要指定对另一个模块的依赖性,请使用require,如下所示:
还有一个 requires static
指令,指示在编译时需要模块,但在运行时是可选模块。这被称为可选依赖项,在本简介中将不再讨论。
requires transitive—implied readability:
要指定对另一个模块的依赖关系并确保其他模块在读取您的模块时也读取该依赖关系(称为隐式可读性),则需要传递,如:
考虑一下java.desktop模块声明中的以下指令:
java.xml
; 在这种情况下,任何读取java.desktop的模块也将隐式读取java.xml。例如,如果java.desktop模块中的方法返回了java.xml模块中的类型,则读取java.desktop的模块中的代码将依赖于java.xml。如果没有在java.desktop的模块声明中使用require传递指令,则此类依赖模块除非明确读取java.xml,否则不会编译。
根据JSR 379,Java SE的标准模块必须在所有情况下(例如此处所述的情况)都隐含可读性。同样,尽管Java SE标准模块可能依赖于非标准模块,但是它一定不能赋予它们隐式的可读性。这样可确保仅依赖Java SE标准模块的代码可跨Java SE实现移植。
exports and exports…to.
exports 模块伪指令指定该模块的一个程序包,其公共类型(及其嵌套的公共和受保护类型)应可被所有其他模块中的代码访问。通过export ... to指令,您可以在逗号分隔的列表中准确指定哪些模块或哪些模块的代码可以访问导出的软件包(称为合格导出)。
uses
Uses Module指令指定此模块使用的服务-使该模块成为服务使用者。服务是实现接口或扩展使用指令中指定的抽象类的类的对象。
provides…with.
带有 provides…with 指定模块提供服务实现,从而使该模块成为服务提供者。指令的Provides部分指定模块的uses指令中列出的接口或抽象类,指令的with部分指定实现接口或扩展抽象类的服务提供者类的名称。
open, opens, and opens…to.
在Java 9之前,无论您是否要允许此功能,反射都可以用于了解包中的所有类型以及该类型的所有成员(甚至是其私有成员)。因此,什么都没有真正封装。
模块系统的主要动机是强大的封装能力。默认情况下,除非是公共类型并且您导出其包,否则其他模块将无法访问该模块中的类型。您仅公开要公开的软件包。对于Java 9,这也适用于反射。
Allowing runtime-only access to a package.形式为opens的模块指令
opens package
表示仅在运行时其他模块中的代码可以访问特定程序包的公共类型(及其嵌套的public和protected)。另外,可以通过反射访问指定包中的所有类型(以及所有类型的成员)。
允许特定模块仅在运行时访问程序包。形式的opens ... to模块指令
表示仅在运行时,列出的模块中的代码才能访问特定程序包的公共类型(及其嵌套的public和protected)。指定包中的所有类型(以及所有类型的成员)都可以通过反射访问指定模块中的代码。
允许仅运行时访问模块中的所有软件包。如果给定模块中的所有软件包都应在运行时访问并通过反射到所有其他模块来访问,则可以 open 整个模块,如下所示:
// module directives
}
6.反射相关
默认情况下,具有运行时反射访问包的模块可以查看包的公共类型(及其嵌套的公共和受保护类型)。 但是,其他模块中的代码可以访问暴露的包中的所有类型以及这些类型中的所有成员,包括通过setAccessible的私有成员,如早期的Java版本一样。