執行時機: 編譯期 → 運行期(JVM 啟動、程序運行),類加載發生在程序運行期間。
階段劃分: 加載 → 連接(驗證、準備、解析) → 初始化 → 使用 → 卸載
執行順序: 大體按上述階段依次執行,但相互交叉:
加載 → 驗證(文件格式) → 繼續加載 → 解析 → 驗證(元數據、字節碼) → 準備 → 初始化
參與角色: Class 文件、Java 虛擬機、類加載器
HotSpot 的 Bootstrap ClassLoader (啟動類加載器) 位於虛擬機內部 (C++ 實現),其他類加載器外置於 JVM (Java 實現)
普通類/接口、數組類(組件類型為基本類型如 int[][]):
java.lang.Class 對象class A extends B → Class<B>private Class<Person> clazz → Class<Person>Class c = Person.class → Class<Person>1. 類加載器層級:
Bootstrap Loader (啟動類加載器)
→ 加載 JAVA_HOME/lib 下字節碼 (rt.jar 等)
→ 路徑由 sun.boot.class.path 指定
Extended Loader (擴展類加載器 ExtClassLoader)
→ 加載 JAVA_HOME/lib/ext 下字節碼
→ 路徑由 java.ext.dirs 指定
AppClass Loader (系統/應用程序類加載器 AppClassLoader)
→ 加載 classpath 下字節碼
→ 路徑由 java.class.path 指定
自定義類加載器
→ 繼承 ClassLoader 重寫 findClass() (JDK1.2+ 推薦)
2. 雙親委派模型關係圖:
[圖片: https://ss0.bdstatic.com/.../timg?image&quality=100...]
關系:父持有子引用 (has-a)
分工:收到加載請求先委派父加載器,父找不到才由子加載
好處:Java 類隨加載器具備優先級層次,保護核心類庫不被篡改
同一 Class 文件被同一類加載器加載,才判定為相等。意義:
equals()、isAssignableFrom()、instanceof、isInstance() 結果才一致。int[][]):直接生成 Class 對象,標記「已加載」。Person[][]):遞歸加載組件類型,每次去掉一個維度。static int i = 20; // 編譯期產生 ConstantValue 屬性,但不存 20
// 準備階段:常規初始化 → i = 0
final static int i = 20; // 編譯期產生 ConstantValue 並存 20
// 準備階段:從 ConstantValue 取值 → i = 20
觸發時機 — 主動引用:
new 實例化main 方法的主類執行順序示例 (筆試高頻):
public class Father {
private static int i = 20;
static { System.out.println("Father static before: " + i); i = 50; System.out.println("Father static after: " + i); }
public Father() { System.out.println("Father constructor: " + i); }
}
public class Son extends Father {
private static int i = 20;
static { System.out.println("Son static before: " + i); i = 50; System.out.println("Son static after: " + i); }
public Son() { System.out.println("Son constructor: " + i); }
}
public class Main {
public static void main(String[] args) { new Son(); }
}
/* 輸出:
Father static before: 20
Father static after: 50
Son static before: 20
Son static after: 50
Father constructor: 50
Son constructor: 50
*/
順序:父類 <clinit> → 子類 <clinit> → 父類 <init> → 子類 <init>
被動引用: 會觸發類加載但不會初始化 (如訪問父類靜態字段、定義對象數組、調用 Class.forName 且 initialize=false 等)。