在完成 PATH 是什麼? 中HelloWorld.java的編譯之後,相同資料夾下就會出現HelloWorld.class,JVM、JRE 與 JDK 說過,JVM的可執行檔副檔名是.class,接下來要啟動JVM,要求JVM執行HelloWorld
指令:
啟動JVM的指令是java
,而要求JVM執行HelloWorld時,只要指定類別名稱(就像執行javac.exe工具程式,只要鍵入javac
就可以了),不用附加.class副檔名,附加.class反而會有錯誤訊息。
接下來,請你試著切換至C:\,想想看,如何執行HelloWorld?以下幾個方式都是行不通的:
你要知道java
這個指令是作什麼用的?正如先前所言,執行java
指令目的在於啟動JVM,之後接著類別名稱,表示要求JVM執行指定的可執行檔(.class)。
在 PATH 是什麼? 中提過,實體作業系統下執行某個指令時,會依PATH中的路徑資訊,試圖找到可執行檔案(例如對Windows來說,就是.exe、.bat副檔名的檔案,對Linux等就是有執行權限的檔案)。
JVM是Java程式唯一認得的作業系統,對JVM來說,可執行檔就是副檔名為.class的檔案。想在JVM中執行某個可執行檔(.class),你就要告訴JVM這個虛擬作業系統到哪些路徑下尋找檔案,方式是透過CLASSPATH
指定其可執行檔(.class)的路徑資訊。
用Windows與JVM作個簡單的對照,就可以很清楚地對照PATH
與CLASSPATH
:
作業系統 |
搜尋路徑 |
可執行檔 |
Windows | PATH |
.exe、.bat |
JVM | CLASSPATH |
.class |
PATH
與CLASSPATH
根本就是不同層次的環境變數,實體作業系統搜尋可執行檔是看PATH
,JVM搜尋可執行檔(.class)只看CLASSPATH
。
如何在啟動JVM時告知可執行檔(.class)的位置?可以使用-classpath
引數來指定:
-classpath
有個縮寫形式-cp
,這比較常用。如果有多個路徑資訊,則可以用分別區隔。例如:
java -cp C:\workspace;C:\classes HelloWorld
JVM會依CLASSPATH
路徑順序,搜尋是否有對應的類別檔案,先找到先贏,先找到先載入。如果在JVM的CLASSPATH
路徑資訊中都找不到指定的類別檔案,JDK7前的版本會出現java.lang.NoClassDefFoundError
訊息,而JDK7之後的版本會有比較友善的中文錯誤訊息。
為什麼一開始的那張圖不用特別指定CLASSPATH
呢?JVM預設的CLASSPATH
就是讀取目前資料夾中的.class,如果自行指定CLASSPATH
,則以你指定的為主。例如:
如上圖所示,雖然工作路徑是在C:\workspace(其中有HelloWorld.class),你啟動JVM時指定到C:\xyz中搜尋類別檔案,JVM還是老實地到指定的C:\xyz中找尋,結果當然就是找不到而顯示錯誤訊息。有的時候,希望也從目前資料夾開始尋找類別檔案,則可以使用.指定。例如:
如果使用Java開發了程式庫,這些程式庫中的類別檔案,會封裝為JAR(Java Archive)檔案,也就是副檔名為.jar的檔案。JAR檔案實際使用ZIP格式壓縮,當中包含一堆.class檔案,那麼,如果你有個JAR檔案,如何在CLASSPATH中設定?
答案是將JAR檔案當作特別的資料夾,例如,有abc.jar與xyz.jar放在C:\lib底下,執行時若要使用JAR檔案中的類別檔案,可以如下:
java -cp C:\workspace;C:\lib\abc.jar;C:\lib\xyz.jar SomeApp
如果有些類別路徑很常使用,其實也可以透過環境變數設定。例如:
SET CLASSPATH=C:\classes;C:\lib\abc.jar;C:\lib\xyz.jar
在啟動JVM時,也就是執行
java
時,若沒使用-cp
或-classpath
指定CLASSPATH
,就會讀取CLASSPATH
環境變數。同樣地,文字模式中的設定在關閉文字模式之後就會失效。如果希望每次開啟文字模式都可以套用某個CLASSPATH
,也可以設定在系統變數或使用者變數中。如果執行時,使用了-cp
或-classpath
指定CLASSPATH
,則以-cp
或-classpath
的指定為主。如果某個資料夾中有許多.jar檔案,從Java SE 6開始,可以使用
*
表示使用資料夾中所有.jar檔案。例如指定使用C:\jars下所有JAR檔案:java –cp .;C:\jars\* cc.openhome.JNotePad
Java SE 6中
CLASSPATH
新的指定方式,也適用在系統環境變數的設定上。