← [ BACK_TO_NOTES ]

Java 类路径与模块系统

classpath 如何定位类,JPMS 模块路径如何显式依赖与导出:两套模型的分工与迁移意识。

#concept #growing #dev #java

[!info] related notes

Java 类路径与模块系统

这个概念为什么出现

JVM 启动后必须知道“到哪里加载类”。经典答案是 classpath;Java 9+ 引入 JPMS 模块系统,用 module-info 声明依赖与导出。现实世界两者并存:应用可能仍以 classpath 为主,JDK 自身强烈模块化。

[!abstract] 一句话理解 classpath 是类查找的历史主路径;模块系统用显式依赖与 exports/opens 强化封装;排障时要分清类在哪条路径、被谁加载。

最小可观察示例

场景:理解运行时如何指定 classpath

# 编译到 out 目录
mkdir -p out
printf 'public class Hi{public static void main(String[] a){System.out.println("hi");}}' > Hi.java
javac -d out Hi.java
java -cp out Hi

期望输出:

hi

模块示例(概念):

// module-info.java
module shop.app {
    requires java.base; // 隐式也可,示意
    exports shop.api;
}

结合场景再看三个关注点

  1. -cp 指向目录/JAR 列表。
  2. classpath 目录指向包目录的根;例如 shop.Hi 的 class 文件应在根下 shop/Hi.class,源码位置则由构建方式决定。
  3. 模块化增加封装,反射默认可能需 opens。

核心概念与准确模型

1. classpath

  • Linux/macOS 用冒号、Windows 用分号分隔目录与 JAR。
  • 在应用加载器搜索 classpath 时,顺序会影响重复类的选择;父加载器委托和已加载的类也影响结果。

2. 模块路径

  • module-info.java:requires 声明读取依赖,exports 导出 public API,opens 开放运行时深反射;provides/uses 声明服务提供与使用。
  • 更强封装与依赖显式化

3. 自动模块与未命名模块

  • 没有模块描述符的普通 JAR 放在 classpath 上,属于对应加载器的未命名模块;放在 module path 上并被解析后,可成为自动模块(名称来自清单或文件名)。
  • 自动模块是有名字的模块,自动导出并开放其包;迁移到显式模块描述符后,需要重新声明访问边界。

4. 与构建工具

  • Maven/Gradle 生成 classpath/module path

边界情况与反直觉行为

  1. 同名类不同 JAR → 隐蔽错误。
  2. 命名模块中的 split package 会受到解析与类加载限制,例如同一模块同时读取两个导出同名包的模块会冲突;不能直接沿用 classpath 中拼接多个 JAR 的做法。
  3. public API 反射不一律需要 opens;跨模块深反射非公开成员时通常才需要定向开放包。

常见误区

[!warning] 常见误区:认为模块系统可忽略 即便应用不写 module-info,也会与模块化 JDK/库交互(jlink、强封装)。

工程实践

  1. 依赖收敛,避免重复类。
  2. 可重现构建与锁定版本。
  3. 排障:jdeps、-verbose:class。
  4. 新库评估是否支持 JPMS。

本节总结

  • classpath 定位类;模块强化边界
  • 冲突与封装是主战场
  • 构建工具是日常入口

自测题

  1. 为什么依赖冲突会“同环境不同行为”?
  2. exports 的作用?
参考答案
  1. 不同机器/打包顺序导致 classpath 上胜出的类不同。
  2. 声明哪些包中的 public 类型/成员可由读取本模块的其他模块访问,也可定向导出;它不会同时开放私有成员的深反射。

延伸阅读与资料来源

资料类型支撑内容
Project Jigsaw / JPMS项目模块系统
java command工具-cp / module path
创建于 2026/7/15 更新于 2026/10/6
Digital Biome
Access

键盘导航

j / k / ↑ / ↓
选择对象
Enter / o
打开选择
/ 或 Ctrl+K
全站搜索
i / f / 1–4
筛选当前列表
g → h / l / p / t / a
首页 / 笔记 / 项目 / 工具 / About
r → 1–9
打开所选对象的关联
u
返回上一页
Esc
关闭浮层 / 取消命令;输入框内清空文本