java如何模块化
模块化编程基础
Java的模块化主要通过module-info.java文件实现,该文件定义了模块的边界、依赖关系和访问权限。模块化系统(JPMS, Java Platform Module System)从Java 9开始引入,旨在解决JAR依赖冲突和封装问题。
创建模块步骤
-
项目结构
模块化项目需遵循特定目录结构:src/ └── com.example.mymodule/ ├── module-info.java // 模块声明文件 └── com/example/mymodule/ └── Main.java // 模块代码 -
定义模块
在module-info.java中声明模块名称、依赖和导出包:module com.example.mymodule { requires java.base; // 依赖基础模块(默认隐式添加) requires transitive java.sql; // 传递依赖 exports com.example.mymodule.api; // 导出包供其他模块使用 }
模块化关键操作
-
依赖管理
使用requires声明对其他模块的依赖。requires transitive表示传递依赖,依赖此模块的模块会自动继承该依赖。 -
封装控制
exports指定对外暴露的包,未导出的包仅模块内部可见。使用opens允许反射访问(如框架需运行时注入时)。
-
服务加载
通过provides和uses实现服务接口与实现的解耦:module com.example.provider { provides com.example.spi.ServiceInterface with com.example.impl.ServiceImpl; } module com.example.consumer { uses com.example.spi.ServiceInterface; }
构建与运行
-
编译模块
javac -d out --module-source-path src $(find src -name "*.java") -
打包为JMOD或JAR

jar --create --file mymodule.jar --module-version 1.0 -C out/com.example.mymodule . -
运行模块
java --module-path out -m com.example.mymodule/com.example.mymodule.Main
常见问题解决
-
模块路径冲突
使用--module-path替代--class-path,确保依赖模块位于模块路径中。 -
未命名模块访问
传统非模块化JAR会被视为“未命名模块”,可通过--add-modules或--add-reads临时解决兼容性问题。 -
反射限制
如需反射访问非导出包,在模块声明中使用opens或运行时添加--add-opens参数。
模块化工具
- jlink
创建自定义运行时镜像,仅包含所需模块:jlink --module-path $JAVA_HOME/jmods:out --add-modules com.example.mymodule --output myruntime
通过模块化,Java应用能更清晰地管理依赖、增强封装性,并优化部署体积。






