1. 程式人生 > >第七章.虛擬機器類載入機制

第七章.虛擬機器類載入機制

類載入的生命週期

類載入的整個生命週期:載入–驗證–準備–解析–初始化–使用–解除安裝 7個階段,其中驗證、準備、解析部分統稱為連線。

類初始化的5中條件

1. 使用new關鍵字例項化物件的時候,讀取或設定一個類的靜態欄位(該欄位不被final修飾)的時候,以及呼叫一個類的靜態方法的時候
2. 使用java.lang.reflect包的方法對類進行反射呼叫的時候
3. 當初始化一個類的時候,如果發現其父類還沒有進行過初始化,則需要先初始化其父類
4. 當虛擬機器啟動的時候,使用者需要指定一個要執行的主類,虛擬機器需要先初始化這個主類
5. 當使用JSK1.7的動態語言支援時,如果一個java.lang.invoke.MethodHandle例項最後的解析結果REFgetStatic、REF

putStatic、REF_invokeStatic的方法控制代碼,並且這個方法控制代碼說對應的類沒有進行過初始化

類載入過程

載入
  1. 通過一個類的全限名來獲取定義此類的二進位制節流。
  2. 將這個位元組流所代表的靜態儲存結構轉化為方法區的執行時資料結構。
  3. 在記憶體中生成一個代表這個類的java.lang.Class物件,作為方法區這個類的各種資料的訪問入口。
驗證

檔案格式驗證
– [x] 是否以魔數0xCAFEBABE開頭
– [x] 主次版本號是否在當前虛擬機器處理範圍之內
– [x] 常量池中的常量是否有不被支援的常量型別
– [x] 指向常量的各種索引值中是否有指向不存在的常量或不符合型別的常量
– [x] CONSTANTUtf8

info型的常量中是否有不符合UTF8編碼的資料
– [x] Class檔案中各個部分及檔案本身是否有被刪除的或附加的其他資訊
– [x] 等等

元資料驗證
– [x] 這個類是否有父類
– [x] 這個類的父類是否繼承了不准許被繼承的類
– [x] 如果這個類不是抽象類,是否實現了其父類或者介面之中要求實現的所有方法
– [x] 類中的欄位方法是否與父類產生矛盾

位元組碼驗證
– [x] 保證任意時刻運算元棧的資料型別與指令程式碼序列都能配合工作
– [x] 保證跳轉指令不會跳轉到方法體以外的位元組碼指令上
– [x] 保證方法體重的型別轉換是有效的

符號引用驗證
– [x] 符號引用中通過字串描述的全限定名是否找到相應的類
– [x] 在指定的類中是否存在符合方法的欄位描述符以及簡單名稱說描述的方法和欄位
– [x] 符號引用中的類、欄位、方法的訪問性是否被當前類訪問

準備

準備階段是正式為類變數分配記憶體並設定類變數初始值(被static修飾的變數)的階段,這些變數所使用的記憶體都將在方法區中進行分配

解析

解析階段就是虛擬機器將常量池內的符號引用替換為直接引用的過程

初始化

初始化就是執行類構造器方法的過程

類載入器

通過一個類的全限定名來獲取描述此類的二進位制位元組流

類與類載入器

類載入器實現類的載入動作,對於任意類需要通過載入器和這個類本身來確定類的唯一性