首先是官方說法:
-classpath:
設置用戶類路徑,它將覆蓋 CLASSPATH 環境變量中的用戶類路徑。若既未指定 CLASSPATH 又未指定 -classpath ,則用戶類路徑由當前目錄構成。
-sourcepath:
指定用以查找類或接口定義的源代碼路徑。與用戶類路徑一樣,源路徑項用分號 (; ) 進行分隔,它們可以是目錄、JAR 歸檔文件或 ZIP 歸檔文件。如果使用包,那麼目錄或歸檔文件中的本地路徑名必須反映包名。
注意:通過類路徑查找的類,如果找到了其源文件,則可能會自動被重新編譯。
官方說法很簡潔,但是具體操作起來總覺得不太清晰,我們還是找幾個例子,來具體分析一下:
具體例子:
假設我們有如下的目錄結構:
src-|
|-foo-|
|-Testfoo.java
|-baz-|
|-Testbaz.java
classes-|
其中Testfoo.java:
package foo;
public class Testfoo {
//....
}
其中Testbaz.java:
package baz;
import foo.Testfoo;
public class Testbaz {
//...
}
也就是說Testbaz對Testfoo有引用。
我們目標是把Testbaz編譯到目錄classes裏面,試用如下的命令:
javac -d classes src\baz\Testbaz.java
命令失敗,因爲找不到它依賴的Testfoo。我們可以用以下三種方式來實現:
1.我們最容易考慮到的就是編譯被依賴的Testfoo類,並將其加入Testbaz的CLASSPATH
javac -d classes src\foo\Testfoo.java
javac -d classes -classpath classes src\baz\Testbaz.java
第二行使用了-classpath,使得編譯器在尋找Testfoo類的時候以classes爲根目錄,根據根目錄和package名,類名最終定 位了需要用的(已編譯出來的)Testfoo類。
2.在編譯Testbaz的時候把被依賴的Testfoo類加入SOURCEPATH
javac -d classes -sourcepath src src\baz\Testbaz.java
在編譯條件裏面加入-verbose可以很清楚的看到,編譯器在尋找Testfoo類的時候,以src爲根目錄,根據根目錄和package名,類 名最終定位了需要用的(源代碼)Testfoo類。
3.把CLASSPATH和SOURCEPATH兩者都加進來
javac -d classes src\foo\Testfoo.java
javac -d classes -sourcepath src -classpath classes src\baz\Testbaz.java
兩個屬性都被加入,編譯器首先會判斷Testfoo.class和Testfoo.java是否同時存在。如果單獨存在,則適應於以上的方法之一。 如果同時存在,則判斷.class是否是.java的最新編譯,如果有差異,則重新編譯.java來覆蓋.class
有必要補充一下-d參數:
-d參數是很好的把源程序和目標代碼分離的參數。-d制定的是目標代碼的根目錄,源文件的包的結構將以目錄形式反映到根目錄上。美中不足的是-d需 要指定已經存在的目錄,不能自動創建。