classpath和module-path是Java中并行的两类加载机制,区别在于是否启用模块系统:classpath加载非模块化内容并归入无名模块,module-path专用于命名模块或自动模块,强制依赖声明与包导出控制,且module-path优先级高于classpath。

Java 中 classpath 和 module-path 是两套独立、并行的类加载机制,不是新旧替代关系,核心区别在于“是否启用模块系统”以及“如何管理依赖与可见性”。
作用对象不同
classpath 加载的是所有非模块化内容:普通 .class 文件、传统 JAR(不含 module-info.class)、资源文件等,全部归入一个叫 unnamed module 的“大杂烩模块”,没有任何封装或访问限制。
module-path 专用于加载模块化构件:只有包含 module-info.class 的 JAR 或目录,才会被识别为命名模块(named module);不带模块声明的 JAR 若被强行放进 module-path,则降级为自动模块(automatic module),名字来自文件名,但包全开放、无 requires 约束。
依赖与可见性规则不同
- classpath 不要求声明依赖,也不控制包是否可被外部使用——所有包默认可访问,容易导致隐式耦合和运行时冲突
- module-path 强制模块在
module-info.java中写明requires和exports,未导出的包对外不可见,JVM 在编译期就能发现“调用了未导出的类”这类问题
查找逻辑与优先级不同
classpath 是线性扫描:JVM 按路径顺序逐个查找类,遇到第一个匹配就停止,同名类可能被遮蔽。
立即学习“Java免费学习笔记(深入)”;
module-path 构建模块图:先确定类属于哪个模块,再在该模块内精确查找,避免跨模块重复扫描;且模块路径优先级高于类路径——即使同名类同时存在于两边,也只加载 module-path 下的那个。
命令行用法与常见误用
-
-cp或--class-path只影响 unnamed module 的加载,对模块内部requires的依赖无效 -
-p或--module-path只参与模块解析,不会让模块内的代码去查 classpath 里的类 - 把含
module-info.class的 JAR 放进 -cp,模块声明直接失效;把普通 JAR 塞进 -p,会变成自动模块,可能引发 split package 错误


















