CLASSPATH 是 Java 虚拟机 用来查找类文件(.class文件)的路径列表,当你的 Java 代码中引用一个类时(import java.util.ArrayList;),JVM 就会按照 CLASSPATH 中设定的路径去寻找对应的 .class 文件。

CLASSPATH 的作用是什么?
CLASSPATH JVM 的“寻路系统”。
想象一下你的 Java 项目就像一个城市,而 .class 文件就是城市里的建筑物,JVM 需要去这些“建筑物”里执行代码。CLASSPATH 就是一份地图,告诉 JVM 去哪些“街道”(目录)或“地标”(具体的 .zip/.jar 文件)里寻找它需要的“建筑物”(.class 文件)。
当一个类被引用时(new ArrayList()),JVM 会按以下顺序查找:
- Bootstrap Classpath (启动类路径): 这是 JVM 内置的路径,用于加载核心 Java 类库(如
java.lang.String),通常在启动时由 JVM 自动设置,用户无需干预。 - Extension Classpath (扩展类路径): 用于加载标准扩展库(位于
JAVA_HOME/jre/lib/ext目录下的 JAR 文件),这个机制在 Java 9+ 中已被模块系统取代。 - User Classpath (用户类路径): 这就是我们通常设置的
CLASSPATH,JVM 会首先在这里查找,如果找不到,才会去 Bootstrap 和 Extension 路径查找。
CLASSPATH 的格式与语法
CLASSPATH 是一个由路径分隔符隔开的字符串列表。

- 在 Windows 系统上,路径分隔符是 分号 。
- 在 Linux 和 macOS 系统上,路径分隔符是 冒号 。
路径可以是以下几种形式:
| 路径类型 | 描述 | 示例 (Windows) | 示例 (Linux/macOS) |
|---|---|---|---|
| 目录路径 | 指定一个包含 .class 文件的根目录。 |
C:\my_project\classes |
/home/user/my_project/classes |
| JAR/ZIP 文件 | 指定一个包含 .class 文件的归档文件。 |
C:\libs\my_lib.jar |
/home/user/libs/my_lib.jar |
| 当前目录 | 指定当前工作目录。 | ||
| 父目录 | 指定当前目录的上一级目录。 |
示例 (Windows):
.;C:\java\lib\tools.jar;D:\my_project\bin
这个 CLASSPATH 包含了:
- : 当前目录
C:\java\lib\tools.jar: 一个 JAR 文件D:\my_project\bin: 一个存放编译后.class文件的目录
示例 (Linux/macOS):

.:~/java/lib/tools.jar:/home/user/my_project/bin
如何设置 CLASSPATH?
有三种主要方式来设置 CLASSPATH,按优先级从高到低排列。
临时设置(仅对当前终端/命令行窗口有效)
这种方式在调试或临时运行特定程序时非常有用。
Windows (CMD):
# 设置 CLASSPATH set CLASSPATH=.;C:\path\to\my\library.jar # 查看当前 CLASSPATH echo %CLASSPATH% # 运行 Java 程序 java com.example.MyApp
Windows (PowerShell):
# 设置 CLASSPATH $env:CLASSPATH=".;C:\path\to\my\library.jar" # 查看当前 CLASSPATH $env:CLASSPATH # 运行 Java 程序 java com.example.MyApp
Linux / macOS (Bash / Zsh):
# 设置 CLASSPATH export CLASSPATH=.:~/path/to/my/library.jar # 查看当前 CLASSPATH echo $CLASSPATH # 运行 Java 程序 java com.example.MyApp
注意:在 Linux/macOS 中,如果路径包含空格,需要用引号括起来,并用反斜杠 \ 转义,或者使用单引号。
永久设置(通过系统环境变量)
这种方式会让系统在任何地方都能识别该变量。
Windows:
- 右键点击“此电脑” -> “属性” -> “高级系统设置”。
- 在“高级”选项卡下,点击“环境变量”。
- 在“系统变量”(推荐)或“用户变量”部分,点击“新建”。
- 变量名:
CLASSPATH - 变量值:
. ; C:\path\to\your\libs\library.jar(注意开头的 和分号) - 确定所有窗口,并重启终端或命令行工具使新配置生效。
Linux / macOS:
通常需要修改 Shell 的配置文件(如 ~/.bashrc, ~/.zshrc, ~/.profile)。
# 打开配置文件 (例如使用 vim) vim ~/.bashrc # 在文件末尾添加以下行 export CLASSPATH=/path/to/your/libs/library.jar:. # 保存文件后,让配置生效 source ~/.bashrc
在运行 Java 命令时通过 -cp 或 -classpath 参数指定
这是最推荐、最灵活、最不容易出错的方式,尤其是在现代开发中,它会临时覆盖任何已设置的 CLASSPATH 环境变量。
# 基本语法 java -cp <路径列表> <主类名> # 示例 java -cp ".;C:\my_libs\utils.jar;D:\project\bin" com.example.Main # 示例 (Linux/macOS) java -cp ".:~/my_libs/utils.jar:/project/bin" com.example.Main
-cp 和 -classpath 是完全等价的。
CLASSPATH 的现代实践与常见误区
现代 Java 开发与 CLASSPATH
在 Java 9 引入模块系统 (JPMS) 之后,以及 Maven/Gradle 等构建工具普及的今天,手动设置系统级的 CLASSPATH 已经非常不常见了。
-
构建工具 (Maven/Gradle):
- 它们会自动管理项目的依赖(JAR 包)和编译输出目录。
- 当你运行
mvn compile或gradle build时,它们会把源代码编译到target/classes(Maven) 或build/classes(Gradle) 目录。 - 当你运行
java -jar your-app.jar时,构建工具会生成一个可执行的 JAR 文件,这个 JAR 文件的 Manifest 文件中已经包含了正确的Class-Path信息,或者它本身就是“胖JAR” (Fat JAR / Uber JAR),包含了所有依赖,你完全不需要手动设置CLASSPATH。
-
Java 模块系统 (JPMS):
- 模块化项目通过
module-info.java文件定义模块和依赖,从根本上改变了类加载机制,不再过分依赖CLASSPATH。
- 模块化项目通过
对于新项目,强烈建议使用构建工具,并避免设置全局的 CLASSPATH 环境变量,只在需要快速测试、运行没有构建工具的小型脚本,或运行老旧项目时,才考虑手动使用 -cp 参数。
常见误区
-
忘记包含当前目录
- 问题:如果你把编译后的
.class文件放在当前目录,但CLASSPATH没有包含 ,JVM 将找不到你的主类。 - 解决:确保
CLASSPATH的开头是 (代表当前目录)。
- 问题:如果你把编译后的
-
路径分隔符错误
- 问题:在 Windows 上用了冒号 ,或者在 Linux/macOS 上用了分号 。
- 解决:根据操作系统使用正确的分隔符。
-
路径末尾有多余的分号/冒号
- 问题:
.;C:\myproject\bin;,末尾的分号/冒号会被解析为一个空字符串路径,通常无害,但是不规范的写法。
- 问题:
-
混淆了
PATH和CLASSPATHPATH:用于告诉操作系统去哪里寻找可执行文件(如java.exe,javac.exe)。CLASSPATH:用于告诉JVM去哪里寻找类文件(如String.class,MyApp.class)。JAVA_HOME:指向 JDK 的安装根目录,PATH变量会引用它来找到bin目录。- 这三者是完全不同的概念,不要混淆。
| 特性 | 描述 |
|---|---|
| 作用 | 告诉 JVM 在哪里查找 .class 文件。 |
| 格式 | 路径列表,用 (Win) 或 (Linux/macOS) 分隔。 |
| 设置方式 | 临时 (set/export)、永久(系统环境变量)、命令行参数 (-cp)。 |
| 现代实践 | 推荐使用 -cp 参数进行临时设置,或完全依赖构建工具(Maven/Gradle),避免设置全局环境变量。 |
| 关键点 | 别忘了 (当前目录),别用错路径分隔符,别混淆 PATH 和 CLASSPATH。 |
