- 一、類生命周期:共7個階段
- 類從被加載到虛擬機內存中開始,到卸載出內存。整個生命周期包括:加載、驗證、准備、解析、初始化、使用和卸載7個階段。
- 其中驗證、准備、解析3個部分統稱為連接。
- 類加載的過程:不包括上面的使用和卸載。
- 示意圖:
- 類從被加載到虛擬機內存中開始,到卸載出內存。整個生命周期包括:加載、驗證、准備、解析、初始化、使用和卸載7個階段。
- 二、類加載各階段說明:(加載只有5個階段,不包括使用和卸載)
- 加載:(完成3步)
- 通過一個全限定類名來獲取定義此類的二進制字節流;
- 將這個字節流的靜態存儲結構轉化為方法區的運行時數據結構;
- 在內存中生成一個代表該類的Class對象,作為方法區這個類的各種數據的訪問入口;
- 驗證:(連接階段的第一步)
- 目的:確保Class文件的字節流中包含的信息符合當前虛擬機的要求,並不會危害虛擬機自身的安全。
- 4個階段:
- 1、文件格式驗證
- 2、元數據驗證
- 3、字節碼驗證
- 4、符號引用驗證
- 准備:
- 正式為類變量分配內存並設置類變量初始值,都在方法區中分配。
- 1、進行內存分配的僅包括類變量(被static修飾的變量),而不包括實例變量。
- 實例變量將會在對象實例化時隨着對象一起分配在Java堆中。
- 2、這里說的初始值“通常情況”下是數據類型的零值,
- 1、進行內存分配的僅包括類變量(被static修飾的變量),而不包括實例變量。
- 正式為類變量分配內存並設置類變量初始值,都在方法區中分配。
- 解析:
- 虛擬機將常量池內的符號引用替換為直接引用的過程。
- 注:符號引用類似於別名,直接引用類似於實際存儲地址;
- 具體解析有:類或接口的解析、字段解析、類方法解析、接口方法解析
- 虛擬機將常量池內的符號引用替換為直接引用的過程。
- 初始化:(類加載過程的最后一步)
- 真正開始執行類中定義的Java程序代碼(或者說是字節碼)
- 初始化階段是執行類構造器<clinit>()方法的過程。
- <clinit>()方法是由編譯器自動收集類中的所有類變量的賦值動作和靜態語句塊(static{}塊)中的語句合並產生的。
- 1、靜態語句塊中只能訪問到定義在靜態語句塊之前的變量,定義在它之后的變量,在前面的靜態語句塊可以賦值,但是不能訪問。
- 2、父類中定義的靜態語句塊要優先於子類的變量賦值操作
- 編譯器收集的順序是由語句在源文件中出現的順序所決定的,
- <clinit>()方法是由編譯器自動收集類中的所有類變量的賦值動作和靜態語句塊(static{}塊)中的語句合並產生的。
- 加載:(完成3步)
- 三、類加載器(頂級在上,次級在先)
- 1、啟動類加載器(頂級)
- 加載<JAVA_HOME>\lib目錄中的類庫(或被-Xbootclasspath參數所指定的路徑中)
- 2、擴展類加載器(開發者可直接使用)
- 加載<JAVA_HOME>\lib\ext目錄中的類庫(或被java.ext.dirs系統變量指定的路徑中的類庫)
- 3、應用程序類加載器(開發者可直接使用)
- 加載用戶類路徑(ClassPath)上所指定的類庫。
- 4、用戶自定義加載器:
- 附:
- 1、啟動類加載器(頂級)
- 四、雙親委派模型
- 要求除了頂層的啟動類加載器外,其余的類加載器都應當有自己的父類加載器。
- 類加載器雙親委派模型:

