有时候我们需要直接用jdk提供的java命令来执行class文件让软件运行起来,经常会发现如下提示:
用IDEA则没有问题。
其实原因很简单,我们忽略了2个细节。
java
指令默认在寻找class文件的地址是通过CLASSPATH
环境变量中指定的目录中寻找的。- 忽略了
package
的影响。
1、package
一个类的全名应该是包名+类名,所以必须按照package定义的路径来存放源文件(除非这个类没有package定义包名),我们在使用java
命令执行类的时候也必须使用类的全名。
2、classpath
比如在运行下面的命令的时候:
package com.example.myspringboot001;
import java.io.File;
import java.util.Random;
class Test {
Test() {
}
public static void main(String[] args) {
File file = new File(".\\./text.txt");
System.out.println(file.exists());
System.out.println("你好");
System.out.println(file.getAbsoluteFile());
System.out.println(System.getProperty("user.dir"));
Random random = new Random();
System.out.println(random.nextInt());
System.out.println(System.getProperty("java.class.path"));
}
}
E:\WorkPlace\IDEA\my-springboot-001\target\classes>java com.example.myspringboot001.Test
E:\WorkPlace\IDEA\my-springboot-001\target\classes
目录下必须要有com.example.myspringboot001
这三个目录,并且在myspringboot001
目录中要有Test.class
文件,才没有问题(com.example.myspringboot001.Test才是完整的类名)。
并且我们在执行java命令的时候没有使用-classpath
(或-cp
)参数,这是因为没有设置这个参数时则使用环境变量中的参数,我们可以看以下环境变量中的参数CLASSPATH
:
.;%Java_Home%\bin;%Java_Home%\lib\dt.jar;%Java_Home%\lib\tools.jar
可以看到最前面的.;
表示当前目录。所以上面的java命令表示在当前目录(E:\WorkPlace\IDEA\my-springboot-001\target\classes)中加载并执行com.example.myspringboot001.Test
类,其中E:\WorkPlace\IDEA\my-springboot-001\target\classes
就叫做类路径。
所以,我们可以在其他的目录中执行java命令,只要保证-classpath
设置的目录中有完整的包结构就行,下面是在E:\WorkPlace\IDEA\my-springboot-001
目录中执行命令:
E:\WorkPlace\IDEA\my-springboot-001>java -cp target/classes com.example.myspringboot001.Test
可以使用下面的代码获取手动设置的类路径:
// 返回手动设置的-classpath。如果没有手动设置-classpath,则返回的是环境变量中的参数CLASSPATH。
System.getProperty("java.class.path")
疑问1
疑问:我们在手动设置-classpath
中没有指定JDK中自带的库,JVM可以找到它们吗?
答:是的,JDK 1.5及以后的版本不再需要在classpath中设置JDK自带的库了,因为JVM会默认查找JDK安装目录下自带的库文件。并且JDK 1.5及以后完全不用设置环境变量CLASSPATH
了,即如果在执行Java命令时没有指定-classpath
,则默认为执行java命令的当前目录为classpath
。
疑问2
疑问:我们什么时候需要手动设置-classpath
?
答:当程序运行时需要用到第三方类或者自定义类的时候,我们就需要手动指定-classpath
。
疑问3
疑问:classpath可以包含哪些文件类型?
答:在Java中,classpath(类路径)可以包含多种类型的文件,但主要关注的是包含.class文件的目录或JAR文件(Java Archive,即Java归档文件)。
以下是classpath可以包含的文件类型:
- 目录:包含.class文件的目录。JVM会在这些目录中查找
.class
文件。 - JAR文件:JAR文件是一种用于打包多个Java类文件、相关元数据和资源(如文本、图像等)到一个文件中的格式。JAR文件可以被Java虚拟机直接读取,作为类路径的一部分。
- ZIP文件:实际上,JAR文件在格式上就是一个ZIP文件,只是它们通常具有.jar扩展名,并且包含Java类文件。因此,任何有效的ZIP文件(如果它包含.class文件)理论上也可以作为classpath的一部分,尽管这不是常见的做法。
当设置classpath时,可以使用分号(Windows)或冒号(Unix/Linux)来分隔多个路径。
# Unix/Linux 示例
java -cp "dir1:dir2:lib/mylib.jar" MyProgram
# Windows 示例
java -cp "dir1;dir2;lib\mylib.jar" MyProgram