Java 的 Classpath 程是編譯順序
Contents
Java 的 Classpath 是 JVM 找到類別檔(.class)和 JAR 的依據,理解它對於編譯與執行 Java 程式都非常重要。
什麼是 Classpath?
Classpath 告訴 Java 編譯器(javac)和 JVM(java)在哪裡尋找:
.class檔(編譯後的位元組碼).jar檔(打包的類別庫)- 資源目錄(包含
.properties、.xml等設定檔)
如果 Classpath 設定不正確,執行時會拋出 ClassNotFoundException 或 NoClassDefFoundError。
設定 Classpath 的方式
1. 使用 -cp 或 -classpath 參數(推薦)
編譯時:
|
|
執行時:
|
|
Windows 環境使用分號
;分隔,Unix/Linux/macOS 使用冒號:分隔。
2. 設定環境變數 CLASSPATH
|
|
⚠️ 不建議設定全域環境變數
CLASSPATH,因為會影響系統所有 Java 程式,容易產生衝突。
多個 JAR 的 Classpath 設定
當依賴的 JAR 很多時,可以使用萬用字元(Java 6+):
|
|
注意:萬用字元 * 只會展開 .jar 檔,不會遞迴子目錄。
編譯期 vs 執行期的 Classpath 差異
| 階段 | 工具 | 說明 |
|---|---|---|
| 編譯期 | javac -cp |
需要包含所有被引用類別的 jar,讓編譯器能找到型別定義 |
| 執行期 | java -cp |
需要包含實際執行時用到的所有 jar,缺少會在 Runtime 拋出例外 |
範例:只有 provided scope 的 jar(如 Servlet API),編譯時需要但執行時由容器(Tomcat)提供,不需加入部署的 classpath。
類別載入順序
JVM 的類別載入器(ClassLoader)有階層結構:
- Bootstrap ClassLoader:載入 Java 核心類別(
java.lang.*等),對應$JAVA_HOME/lib - Extension ClassLoader:載入
$JAVA_HOME/lib/ext下的類別 - Application ClassLoader:載入使用者指定的 Classpath
載入順序遵循「雙親委派模型」,先由上層嘗試載入,找不到才交給下層。若同一個類別名稱出現在多個 JAR 中,Classpath 排在前面的 JAR 優先被載入。
常見問題排查
|
|