一、類加載的過程
1、加載
(1)通過類的全限定類名來獲取該類的二進制字節流
(2)將字節流代表的靜態存儲結構轉化爲方法區運行時的數據結構
(3)在內存中生成一個代表該類的java.lang.Class對象,作爲這個類的各種數據的訪問入口
2、鏈接
確保Class文件的字節流中包含的信息符合虛擬機的要求,不會危害虛擬機的自身安全
(1)驗證
-
格式驗證
- 元數據驗證
- 字節碼校驗
(2)準備
爲類變量分配內存並設置類變量的初始值
這些變量所使用的內存都將在方法區中進行分配。
1、內存分配的僅包括類變量(被static修飾的變量),而不包括實例變量,實例變量將會在對象實例化時隨着對象一起分配在Java堆中。
2、初始值“通常情況”下是數據類型的零值,假設一個類變量的定義爲:
public static int value=123;
那變量value在準備階段過後的初始值爲0而不是123,因爲這時候尚未開始執行任何Java方法,而把value賦值爲123的public static指令是程序被編譯後。
(3)解析
虛擬機將常量池中的符號引用替換爲直接飲用
3、初始化
執行構造器中的代碼
初始化階段是執行類構造器<clinit>()方法的過程。<clinit>()方法是由編譯器自動收集類中的所有類變量的賦值動作和靜態語句塊(static{}塊)中的語句合併產生的,編譯器收集的順序是由語句在源文件中出現的順序所決定的。
二、常用的類加載器
1、啓動類加載器(Bootstrap ClassLoader)
用來加載java核心類庫,無法被java程序直接引用
2、擴展類加載器(Extension ClassLoader)
它用來加載 Java 的擴展庫。Java 虛擬機的實現會提供一個擴展庫目錄。該類加載器在此目錄裏面查找並加載Java 類
3、系統類加載器(System ClassLoader)
它根據 Java 應用的類路徑(CLASSPATH)來加載 Java 類。一般來說,Java 應用的類都是由它來完成加載的。
可以通過ClassLoader.getSystemClassLoader()來獲取它
4、用戶自定義類加載器
通過繼承java.lang.ClassLoader類的方式實現