Java模块化编程实战指南

这是一个演示 Java 9 模块化编程逐步演进的示例程序。要成功执行,你需要按照模块化项目的结构来组织代码和编译运行。

项目结构与模块划分

整个程序涉及多个模块,其依赖关系如下:

模块名称 描述 依赖关系 关键导出/声明
appfuncs 核心数学函数模块 依赖 appsupport (Listing 9) 导出 appfuncs.simplefuncs
appsupport 支持函数模块 导出 appsupport.supportfuncs
appstart 主应用程序模块 依赖 appfuncs, userfuncs (Listing 20) uses 服务接口 BinFuncProvider
userfuncs 用户函数接口模块 导出 userfuncs.binaryfuncs
userfuncsimp 用户函数实现模块 依赖 userfuncs (Listing 18) provides 服务实现 AbsPlusProvider, AbsMinusProvider

执行步骤

  1. 创建目录结构

按照模块名创建对应的目录,并将 .java 文件放入正确的包路径下。

bash 复制代码
# 项目根目录 (例如:/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 的内容 (最终版)
  1. 编译模块

必须按照模块间的依赖顺序进行编译。先编译被依赖的模块。

bash 复制代码
# 在项目根目录下执行
# 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.java
  1. 运行程序

使用 java 命令并指定模块路径和主模块/主类 。

bash 复制代码
java --module-path out -m appstart/appstart.mymodappdemo.MyModAppDemo
  1. 预期输出

如果一切配置正确,程序将输出以下结果:

复制代码
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 模块的内容,无需再次声明 。

参考来源

相关推荐
T型码农要学习2 小时前
开源项目5|FileBrowser:免费在线文件管理器!随时随地管控服务器文件
运维·服务器·人工智能·开源
智恒百亿2 小时前
8 卡 RTX 5090 服务器深度实测:256GB 显存能否支撑 70B 模型微调?选型参考
大数据·运维·服务器·人工智能
ai小陈4 小时前
PyTorch DataLoader数据加载性能排查:GPU利用率低的实操指南
人工智能·pytorch·python·深度学习·ai·gpu算力
测试者家园6 小时前
为什么意图驱动测试是自动化测试的下一站,而不是替代品
自动化测试·软件测试·人工智能·持续测试·ai赋能·智能化测试·软件测试变革
D202020207 小时前
TikTok Shop禁止AI语音直播落地后,跨境卖家如何通过达秘合规调整带货内容
人工智能
像风一样自由20207 小时前
20.Milvus常见问题检索不到维度错误和数据一致性
人工智能·大模型·milvus
现代野蛮人7 小时前
【深度学习实验】—— 基于 LSTM 与 Optuna 调参的丙型肝炎预测
人工智能·深度学习·lstm
支支დ7 小时前
VO by Vercel 前端特定优势:为什么它是构建 AI 应用的新范式
前端·人工智能
ZGIAI8 小时前
ZGI 让那些"等你去处理"的事,真正跑起来
人工智能·架构
ZGIAI8 小时前
ZGI:别再做Agent Demo了,先问问它在业务里能不能撑过下周三
人工智能·架构