先看下定义:
-
-classpath 类路径
设置用户类路径,它将覆盖 CLASSPATH 环境变量中的用户类路径。若既未指定 CLASSPATH 又未指定 -classpath,则用户类路径由当前目录构成。有关详细信息,请参阅设置类路径。若未指定 -sourcepath 选项,则将在用户类路径中查找类文件和源文件。
-
-sourcepath 源路径
指定用以查找类或接口定义的源代码路径。与用户类路径一样,源路径项用分号 (:) 进行分隔,它们可以是目录、JAR 归档文件或 ZIP 归档文件。如果使用包,那么目录或归档文件中的本地路径名必须反映包名。注意:通过类路径查找的类,如果找到了其源文件,则可能会自动被重新编译。
这里-classpath和-sourcepath指定的都是被编译的源文件需要调用另外的用户自定义类或源文件的位置。
可以理解为
- -classpath用来指定搜索类文件(*.class文件)的路径,-sourcepath用来指定搜索源文件(*.java文件)的路径
- 如果未指定-sourcepath,那边将会在classpath指定的路径中查找类文件(*.class文件)和源文件(*.java文件)
- 如果找到了源文件(*.java文件),可能会重新生成类文件(*.class文件)
下面我们来验证下第一点(同时指定-classpath和-sourcepath参数):
新建一个HelloWorld.java文件
package a.b;
public class HelloWorld{
public static void main(String[] args){
System.out.println("Hello World!");
}
}
在命令行执行
$ javac -verbose -classpath ~ -sourcepath ~/Downloads HelloWorld.java
-verbose参数可以帮我们输出详细的编译信息,在命令中我们指定classpath为,sourcepath为/Downloads。
如上图可以看到:类文件的搜索路径包含/User/gaozengrong,源文件的搜索路径为/User/gaozengrong/Downloads,就如我们再命令中指定的一样(“~”符号在linux和mac等系统中代表用户目录)。
验证第二点(只指定-classpath文件)
在命令行直接执行
$ javac -verbose -classpath ~ HelloWorld.java
显而易见,类文件的搜索路径和源文件的搜索路径均为/User/gaozengrong
验证第三点(源文件是否会被重新编译)
我们新建两个源文件分别如下:
package a.b;
import c.d.T;
public class TestT {
public static void main(String[] args) {
T t = new T();
t.p();
}
}
package c.d;
public class T {
public void p(){
System.out.println("class:T");
}
}
目录结构为:
在用户目录下编译TestT.java文件,
javac -verbose -classpath src -sourcepath src src/a/b/TestT.java
如箭头所指,由于TestT类中引用了T类,在编译过程中会加载T.java文件并解析编译。(至于为何先生成TestT.class文件再生成T.class文件,我猜测是T.java文件解析完成后,就可以直接编译生成TestT.class文件)
我们再运行一次编译命令
javac -verbose -classpath src -sourcepath src src/a/b/TestT.java
此时由于已经存在T.class类文件,编译的时候直接加载了T.class文件,而没有加载T.java文件再重新进行自动编译。
我们对T.java文件稍加修改,只添加一条注释即可,修改后的T.java文件为
package c.d;
public class T {
public void p(){
//稍加修改
System.out.println("class:T");
}
}
此时的src文件夹的目录结构:
我们再运行一次编译命令
javac -verbose -classpath src -sourcepath src src/a/b/TestT.java
可以看到,T.java文件被重新加载并进行了编译。
可以得出结论:源文件是否被重新自动编译取决于源文件是否已被修改。