https://www.oracle.com/corporate/features/understanding-java-9-modules.html
Module Declarations
As we mentioned, a module must provide a module descriptor—metadata that specifies the module’s dependencies, the packages the module makes available to other modules, and more. A module descriptor is the compiled version of a module declaration that’s defined in a file named module-info.java. Each module declaration begins with the keyword module, followed by a unique module name and a module body enclosed in braces, as in:
A key motivation of the module system is strong encapsulation.
module modulename {
}
The module declaration’s body can be empty or may contain various module directives, including requires, exports, provides…with, uses and opens (each of which we discuss). As you’ll see later, compiling the module declaration creates the module descriptor, which is stored in a file named module-info.class in the module’s root folder. Here we briefly introduce each module directive. After that, we’ll present actual module declarations.
The keywords exports, module, open, opens, provides, requires, uses, with, as well as to and transitive, which we introduce later, are restricted keywords. They’re keywords only in module declarations and may be used as identifiers anywhere else in your code.
requires. A requires module directive specifies that this module depends on another module—this relationship is called a module dependency. Each module must explicitly state its dependencies. When module A requires module B, module A is said to read module B and module B is read by module A. To specify a dependency on another module, use requires, as in:
requires modulename;
There is also a requires static directive to indicate that a module is required at compile time, but is optional at runtime. This is known as an optional dependency and won’t be discussed in this introduction.
requires transitive—implied readability. To specify a dependency on another module and to ensure that other modules reading your module also read that dependency—known as implied readability—use requires transitive, as in:
requires transitive modulename;
Consider the following directive from the java.desktop module declaration:
requires transitive java.xml;
In this case, any module that reads java.desktop also implicitly reads java.xml. For example, if a method from the java.desktop module returns a type from the java.xml module, code in modules that read java.desktop becomes dependent on java.xml. Without the requires transitive directive in java.desktop’s module declaration, such dependent modules will not compile unless they explicitly read java.xml.
According to JSR 379 Java SE’s standard modules must grant implied readability in all cases like the one described here. Also, though a Java SE standard module may depend on non-standard modules, it must not grant implied readability to them. This ensures that code depending only on Java SE standard modules is portable across Java SE implementations.
exports and exports…to. An exports module directive specifies one of the module’s packages whose public types (and their nested public and protected types) should be accessible to code in all other modules. An exports…to directive enables you to specify in a comma-separated list precisely which module’s or modules’ code can access the exported package—this is known as a qualified export.
uses. A uses module directive specifies a service used by this module—making the module a service consumer. A service is an object of a class that implements the interface or extends the abstract class specified in the uses directive.
provides…with. A provides…with module directive specifies that a module provides a service implementation—making the module a service provider. The provides part of the directive specifies an interface or abstract class listed in a module’s uses directive and the with part of the directive specifies the name of the service provider class that implements the interface or extends the abstract class.
open, opens, and opens…to. Before Java 9, reflection could be used to learn about all types in a package and all members of a type—even its private members—whether you wanted to allow this capability or not. Thus, nothing was truly encapsulated.
A key motivation of the module system is strong encapsulation. By default, a type in a module is not accessible to other modules unless it’s a public type and you export its package. You expose only the packages you want to expose. With Java 9, this also applies to reflection.
Allowing runtime-only access to a package. An opens module directive of the form
opens package
indicates that a specific package’s public types (and their nested public and protected types) are accessible to code in other modules at runtime only. Also, all the types in the specified package (and all of the types’ members) are accessible via reflection.
Allowing runtime-only access to a package by specific modules. An opens…to module directive of the form
opens package to comma-separated-list-of-modules
indicates that a specific package’s public types (and their nested public and protected types) are accessible to code in the listed modules at runtime only. All of the types in the specified package (and all of the types’ members) are accessible via reflection to code in the specified modules.
Allowing runtime-only access to all packages in a module. If all the packages in a given module should be accessible at runtime and via reflection to all other modules, you may open the entire module, as in:
open module modulename {
// module directives
}
本文深入探讨Java 9的模块系统,解析模块声明、依赖、导出、使用和服务提供等核心概念。通过实例说明强封装如何提升代码质量和可维护性。
1065

被折叠的 条评论
为什么被折叠?



