7.1.1 Module Declaration Explained
The module declaration in Java is a fundamental aspect of the Java Platform Module System (JPMS) introduced in Java 9. It allows developers to define the structure and dependencies of their applications in a modular way. Understanding module declarations is crucial for creating modular, maintainable, and scalable Java applications.
Key Concepts
1. Module Declaration Syntax
A module declaration is defined in a file named module-info.java
located in the root of the module's source directory. The declaration starts with the keyword module
followed by the module name and a block containing various module directives.
Example
module com.example.mymodule { requires java.base; exports com.example.mymodule.api; }
2. Module Name
The module name is a unique identifier for the module. It follows the same naming conventions as package names, typically using reverse domain name notation. The module name is used to reference the module in other module declarations and in the module path.
Example
module com.example.mymodule { // Module directives }
3. Requires Directive
The requires
directive is used to declare dependencies on other modules. It specifies that the current module depends on the functionality provided by the named module. The requires
directive can also include modifiers like transitive
and static
.
Example
module com.example.mymodule { requires java.base; requires transitive com.example.anothermodule; }
4. Exports Directive
The exports
directive is used to make packages within the module accessible to other modules. Only the exported packages are visible to other modules, ensuring encapsulation and controlled access to the module's API.
Example
module com.example.mymodule { exports com.example.mymodule.api; }
5. Opens Directive
The opens
directive is used to allow reflective access to packages within the module. This is particularly useful for frameworks and tools that rely on reflection, such as dependency injection libraries.
Example
module com.example.mymodule { opens com.example.mymodule.internal; }
6. Uses and Provides Directives
The uses
directive is used to declare a service dependency, while the provides
directive is used to declare a service implementation. These directives are part of the ServiceLoader mechanism, which allows for loose coupling between service providers and consumers.
Example
module com.example.mymodule { uses com.example.mymodule.api.MyService; provides com.example.mymodule.api.MyService with com.example.mymodule.impl.MyServiceImpl; }
Examples and Analogies
Think of a module declaration as a blueprint for a building. The module name is the address of the building, the requires
directive is the list of materials needed to construct the building, the exports
directive is the list of rooms open to the public, and the opens
directive is the list of rooms that can be accessed by maintenance personnel. The uses
and provides
directives are like the building's services, such as electricity and plumbing, that are provided by external contractors but used by the building's occupants.
By mastering module declarations, you can create well-structured, modular Java applications that are easier to maintain, test, and scale. This modular approach is essential for modern Java development and is a key skill for any Java developer aiming for the Oracle Certified Professional Java SE 11 Developer certification.