classpath 的解釋:
-classpath:
設定使用者類路徑,它將覆蓋 CLASSPATH 環境變數中的使用者類路徑。若既未指定 CLASSPATH 又未指定 -classpath,則使用者類路徑由目前的目錄構成。
-sourcepath:
指定用以尋找類或介面定義的原始碼路徑。與使用者類路徑一樣,源路徑項用分號 (;) 進行分隔,它們可以是目錄、JAR 歸檔檔案或 ZIP 歸檔檔案。如果使用包,那麼目錄或歸檔檔案中的本地路徑名必須反映包名。
通過類路徑尋找的類,如果找到了其源檔案,則可能會自動被重新編譯。
以上的說法很簡潔,但是具體操作起來總覺得不太清晰,我們還是找幾個例子,來具體分析一下:
具體例子:
一:
當在編譯servlet時候,必須得指定類包,也就是指定相應的源檔案, 進行編譯, 否則回找不到import的類包。
tomcat的目錄結構如上:<喎?http://www.bkjia.com/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHA+CsjnufvSqrHg0utjbGFzc2VzxNq1xENoMVNlcnZsZXQuamF2YSDOqkNoMXNlcnZsZXQuY2xhc3Mgzai5/SBqYXZhYyBDaDFTZXJ2bGV0LmphdmEgysfN6rK7s8m1xKOhPC9wPgo8cD4K1eLA777N08O1vcHLY2xhc3NwYXRoo6wg1dK1vbCy17DEv8K8z8K1xHNlcnZsZXQtamFyIMDgsPy9+NDQseDS67LFv8nS1LHg0uuzyUNoMXNlcnZsZXQuY2xhc3M8L3A+CjxwPgq8tKO6amF2YWMgLWNsYXNzcGF0aCAveW91ciBwYXRoL3RvbWNhdC9saWIvc2VydmxldC1hcGkuamFyICAtZCBjbGFzc2VzICAuL2NsYXNzZXMvQ2gxU2VydmxldC5qYXZhPC9wPgo8cD4Kvs3U2mNsYXNzZXPEv8K8z8LJ+rPJwctDaDFTZXJ2bGV0LmNsYXNzPC9wPgo8cD4KPGJyPgo8L3A+CjxwPgrS1M/CtcSyv7fWo6zNqLn91dLBy9K70KnXysHPo6zKx7nY09pjbGFzc3BhdGi1xMbky/u9sr3io7o8L3A+CjxwPgq2/qO6PC9wPgo8cD4KvNnJ6M7Sw8fT0Mjnz8K1xMS/wry94bm5o7o8L3A+CjxwPgogICAgc3JjLQ=="
|-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需要指定已經存在的目錄,不能自動建立。