類加載

類的生命週期:

類的生命週期
  • 加載和鏈接,鏈接不是完全等加載完畢之後才執行,而是一個並行執行的過程;
  • 初始化的情況:
    • 遇到new、getstatic、putstatic、invokestatic這4條字節碼指令時,如果類沒有進行初始化,則需要先觸發初始化;
    • 使用Java.lang.reflect包的方法對類進行反射調用的時候,如果沒有進行過初始化,則需要先觸發其初始化;
    • 當初初始化一個類的時候,如果其父類還沒有初始化,需要先初始化父類;
    • 當虛擬機啓動時,用戶需要指定一個要執行的主類(包含main()方法的類),虛擬機會先初始化這個主類。
  • 不被初始化的情況:
    • 通過子類引用父類的靜態字段;
    • 通過數組定義來引用類;
    • 調用類的常量;

類加載過程: 

類加載過程

加載:

  •  通過一個類的全限定名來獲取定義此類的二進制流

  • 將這個字節流所代表的靜態存儲結構轉化爲方法區的運行時數據結構

  • 在內存中生成一個代表這個類的Class的對象,作爲這個類的各種數據的訪問入口

  驗證:

  • 驗證是連接的第一步,這一階段的目的是爲了確保Class文件的字節流中包含的信息符合當前虛擬機的要求,並且不會危害虛擬機的自身安全
  • 文件格式驗證
  • 元數據驗證
  • 字節碼驗證
  • 符號引用驗證

準備:

  • 準備階段正式爲類變量分配內存並設置變量的初始值。這些變量使用的內存都將在方法區中進行分配。

  • 這裏的初始值並非我們指定的值,而是其默認值,但如果被final修飾的變量,在準備過程中,常量值會被一同設定。

解析: 

  •  解析階段是虛擬機將常量池中的符號引用替換爲直接引用的過程
  • 類或者接口的解析
  • 字段解析
  • 類方法解析
  • 接口方法解析

初始化: 

  •  類初始化階段是類加載過程的最後一步,前面類加載的過程中除了在加載階段用戶應用程序可以通過自定義類加載器參與外,其餘動作完全由虛擬機主導與控制。
  • 到了初始化階段,纔是真正執行類中定義的Java程序代碼
  • 在準備階段,變量已經賦過一次系統要求的初始值,而在初始化階段,則根據開發者通過程序控制制定的主觀計劃去初始化類變量和其他資源
  • 初始化階段是執行類構造器<clinit>方法的過程。