Java 模块系统:封装与依赖管理
了解 Java 9 引入的模块化系统(Project Jigsaw),如何定义模块、控制导出和依赖,构建更可靠的应用程序。 · 难度:入门 · +15XP
模块化动机
大型项目常遇到类路径地狱、内部 API 被滥用、缺少强封装。Java 模块系统通过 module-info.java 显式声明模块的依赖和导出包。
基本结构
// module-info.java
module com.example.myapp {
requires java.sql; // 依赖模块
exports com.example.myapp.api; // 导出包给其他模块
exports com.example.myapp.spi;
provides com.example.Service with com.example.impl.MyService; // 服务提供
}常用指令
| 指令 | 说明 |
|---|---|
| requires | 声明依赖另一个模块 |
| exports | 允许其他模块访问指定包 |
| opens | 允许反射访问(如 Hibernate) |
| provides ... with | 服务提供者 |
| uses | 服务消费者 |
模块化示例
假设有两个模块:com.example.utils 和 com.example.app。
// utils/src/main/java/module-info.java
module com.example.utils {
exports com.example.utils.string;
}
// app/src/main/java/module-info.java
module com.example.app {
requires com.example.utils;
}
如果 app 模块尝试访问 utils 中没有导出的包,编译会失败。
未命名模块
没有 module-info.java 的代码属于未命名模块,可以访问所有导出的模块,但无法使用模块系统的封装优势。
练习提示
在 starter_code 中,我们模拟一个简单的模块定义,请添加 exports 指令使得外部可以访问 com.example.greeting 包。