類載入-載入時機學習

hatch發表於2018-07-01

類載入機制就是虛擬機器把class檔案載入到記憶體,並對其進行校驗、轉換解析、連線、和初始化,從而形成能被虛擬機器使用的Java型別。

生命週期

類從載入到記憶體到解除安裝,整個生命週期包括:

載入
連線(驗證、準備、解析)
初始化
使用解除安裝
複製程式碼

載入時間

什麼時候進行類載入,虛擬機器並沒有強制約束,但對於初始化階段,虛擬機器規範規定了只有下面5中情況對類進行初始化

1.遇到new、getstatic、putstatic、invokestatic位元組指令時,如果類沒有初始化過,則需先觸發其初始化。即new物件例項、讀取設定靜態欄位以及呼叫靜態方法時

2.使用反射包下的方法對類進行反射呼叫時,若果類沒有初始化過,則觸發初始化

3.如果其父類沒有初始化時

4.虛擬機器啟動時,使用者需指定要執行的主類及包含main方法,會先初始化主類

5.動態語言,如果java.lang.invoke.MethodHandler例項最後的解析結果REF_getStatic、REF_putStatic
 、REF_invokeStatic的方法控制程式碼,並且這個方法控制程式碼對應的類沒有進行初始化
複製程式碼

這5種場景是對類的主動引用,除此之外,所有引用類的方式都不會觸發初始化,稱為被動引用。

被動引用

被動引用示例:

1.通過子類引用父類的靜態屬性,子類不會初始化

2.通過陣列定義引用類,不會觸發其初始化

3.常量在編譯階段會存入呼叫類的常量池,呼叫常量不會觸發定義常量的類的初始化

複製程式碼

介面載入過程

介面載入過程和類的載入有些不同:

1.類使用static{}塊初始化資訊;介面不使用static塊載入,但是編譯器會為介面生成<clinit>()類構造器。

2.介面在初始化時,並不要求其發介面全部都完成初始化,只有在真正用到父介面時才會初始化;這點與類不一樣。
複製程式碼

相關文章