classpath
classpath
是JVM
用到的一个环境变量,它用来指示JVM如何搜索class
。
由于
Java
是编译型语言,源码文件是.java
,而编译后的.class
文件才是真正可以被JVM执行的字节码。因此,JVM需要知道,如果要加载一个x.y.z
的类,应该去哪搜索对应的Hello.class
文件。
所以,
classpath
就是一组目录的集合,它设置的搜索路径与操作系统相关(Windows 下为英文逗号,Linux下为英文冒号,带空格的目录用英文双引号括起来)。
classpath有两种指定方法:
- 在系统环境变量中设置 classpath 环境变量;(不推荐)
- 在启动 JVM 时设置 classpath 变量:给java命令传入-classpath或-cp参数;
Jar
jar 是按照 pacckage 组织的目录层级,以及各个目录下的所有文件打成的一个压缩包。
jar 包本质上是一个 zip 格式的压缩文件。
如果我们要执行一个 jar 包的 class,就可以把 jar 包放到 classpath 中。这样JVM就会自动在jar中区搜索某个类。此时可以把 jar 包看作一个目录。
MANIFEST.MF
MANIFEST.MF
是 jar 包包含的一个特殊的纯文本,可以指定 Main-Class
和其他信息。
JVM会自动读取这个MANIFEST.MF
文件,如果存在Main-Class
,我们就不必在命令行指定启动的类名,而是用更方便的命令:
java -jar XXX.jar
jar包还可以包含其它jar包,这个时候,就需要在MANIFEST.MF
文件里配置classpath
了。
在大型项目中,不可能手动编写MANIFEST.MF
文件,再手动创建zip包。Java社区提供了大量的开源构建工具,例如Maven,可以非常方便地创建jar包。
classpath 与 java.class.path
- classpath:指示JVM如何搜索类文件的环境变量,通过 System.getEnv() 获取
- java.class.path:java 参数,通过 System.getProperty() 获取
二者关系:
见jdk 源码中的注释——java.c 中:
/*
* For our tools, we try to add 3 VM options:
* -Denv.class.path=<envcp>
* -Dapplication.home=<apphome>
* -Djava.class.path=<appcp>
* <envcp> is the user's setting of CLASSPATH -- for instance the user
* tells javac where to find binary classes through this environment
* variable. Notice that users will be able to compile against our
* tools classes (sun.tools.javac.Main) only if they explicitly add
* tools.jar to CLASSPATH.
* <apphome> is the directory where the application is installed.
* <appcp> is the classpath to where our apps' classfiles are.
*/
static jboolean
AddApplicationOptions(int cpathc, const char **cpathv)
{
启动 java 程序时,会根据 classpath 拼接 java.class.path 。