这是一个演示 Java 9 模块化编程逐步演进的示例程序。要成功执行你需要按照模块化项目的结构来组织代码和编译运行。项目结构与模块划分整个程序涉及多个模块其依赖关系如下模块名称描述依赖关系关键导出/声明appfuncs核心数学函数模块依赖appsupport(Listing 9)导出appfuncs.simplefuncs包appsupport支持函数模块无导出appsupport.supportfuncs包appstart主应用程序模块依赖appfuncs,userfuncs(Listing 20)uses服务接口BinFuncProvideruserfuncs用户函数接口模块无导出userfuncs.binaryfuncs包userfuncsimp用户函数实现模块依赖userfuncs(Listing 18)provides服务实现AbsPlusProvider,AbsMinusProvider执行步骤1. 创建目录结构按照模块名创建对应的目录并将.java文件放入正确的包路径下。# 项目根目录 (例如/java-module-demo) ├── appsupport │ └── src │ └── appsupport │ ├── module-info.java # Listing 7的内容 │ └── appsupport │ └── supportfuncs │ └── SupportFuncs.java # Listing 6 的内容 ├── appfuncs │ └── src │ └── appfuncs │ ├── module-info.java # Listing 9 的内容 (最终版) │ └── appfuncs │ └── simplefuncs │ └── SimpleMathFuncs.java # Listing 8 的内容 (最终版) ├── userfuncs │ └── src │ └── userfuncs │ ├── module-info.java # Listing 17 的内容 │ └── userfuncs │ └── binaryfuncs │ ├── BinaryFunc.java # Listing 11的内容 │ └── BinFuncProvider.java # Listing 12 的内容 ├── userfuncsimp │ └── src │ └── userfuncsimp │ ├── module-info.java # Listing 18 的内容 │ └── userfuncsimp │ └── binaryfuncsimp │ ├── AbsPlus.java # Listing 13 的内容 │ ├── AbsMinus.java # Listing 14 的内容 │ ├── AbsPlusProvider.java # Listing 15 的内容 │ └── AbsMinusProvider.java # Listing 16 的内容└── appstart └── src └── appstart ├── module-info.java # Listing 20 的内容 (最终版) └── appstart └── mymodappdemo └── MyModAppDemo.java # Listing 19 的内容 (最终版)2. 编译模块必须按照模块间的依赖顺序进行编译。先编译被依赖的模块。# 在项目根目录下执行 # 1. 编译 appsupport模块 javac -d out/appsupport \ appsupport/src/appsupport/module-info.java \ appsupport/src/appsupport/appsupport/supportfuncs/SupportFuncs.java # 2. 编译 userfuncs 模块 javac -d out/userfuncs \ userfuncs/src/userfuncs/module-info.java \ userfuncs/src/userfuncs/userfuncs/binaryfuncs/*.java # 3. 编译 userfuncsimp 模块 (依赖 userfuncs) javac --module-path out -d out/userfuncsimp \ userfuncsimp/src/userfuncsimp/module-info.java \ userfuncsimp/src/userfuncsimp/userfuncsimp/binaryfuncsimp/*.java # 4. 编译 appfuncs 模块 (依赖 appsupport) javac --module-path out -d out/appfuncs \ appfuncs/src/appfuncs/module-info.java \ appfuncs/src/appfuncs/appfuncs/simplefuncs/SimpleMathFuncs.java # 5. 编译 appstart 模块 (依赖 appfuncs, userfuncs) javac --module-path out -d out/appstart \ appstart/src/appstart/module-info.java \ appstart/src/appstart/appstart/mymodappdemo/MyModAppDemo.java3. 运行程序使用java命令并指定模块路径和主模块/主类 。java --module-path out -m appstart/appstart.mymodappdemo.MyModAppDemo4. 预期输出如果一切配置正确程序将输出以下结果2 is a factor of 10 Smallest factor common to both 35 and 105 is 5 Largest factor common to both 35 and 105 is 7 Result of absPlus function: 16 Result of absMinus function: 8核心概念解析模块声明 (module-info.java)每个模块的根目录下必须有此文件用于定义模块名、依赖 (requires)、导出包 (exports) 和服务声明 (provides...with/uses) 。封装性未被exports的包在模块外不可见增强了代码的封装性和安全性 。服务与提供者这是 Java 模块化中的高级特性。userfuncs模块定义了服务接口 (BinaryFunc,BinFuncProvider)userfuncsimp模块提供了具体实现appstart模块通过ServiceLoader动态发现和使用这些服务实现了松耦合 。传递依赖 (requires transitive)在appfuncs的模块声明中requires transitive appsupport;使得依赖appfuncs的模块如appstart也能自动访问appsupport模块的内容无需再次声明 。参考来源java9模块化编程示例解释Java的模块化系统以及如何在项目中应用模块化Java模块化编程的艺术揭开模块化世界的面纱Java编程实践与模块化编程的探索Java模块化