1. 程式人生 > >JAVA類 初始化過程

JAVA類 初始化過程

在Java的物件產生的時候虛擬機器jvm會做一系列的行為,而理解這些行為將有助於我們更深入的理解Java
當我們第一次呼叫一個類的某個靜態方法或訪問某個靜態變數時將首先發生類載入,其過程如下

  1. Java虛擬機器JVM會先去方法區中查詢是否已經載入java類名.class如果已經載入將執行下一步,如果沒有載入則將通過類的完全限定名找到相應的.class檔案載入到方法區並建立一個Class物件,靜態變數只在Class物件首次載入時初始化。

  2. 載入完成後,將首先將Class物件中的非靜態內容載入到方法區的非靜態區中

  3. 然後再載入靜態內容:

  • 首先將靜態內容載入到靜態區中

  • 靜態內容載入完成之後,首先對靜態變數進行預設初始化(基本資料型別賦值為預設值,引用型別為null)

  • 然後對靜態變數進行顯式初始化(即初始化為我們程式所給的值)

  • 接著執行靜態程式碼塊中的程式碼(形如static{…})

  • 類載入過程結束

當我們呼叫Object obj = new Object();建立物件時,首先需要明白即使沒有顯示的使用static關鍵詞,但是構造器實際也是靜態方法,因此在建立物件時也將先執行類的載入,然後執行下列過程:

  1. 首先new Object()在堆中為Object物件分配足夠的儲存空間

  2. 將這段儲存空間清零,然後將所有類的非靜態內容載入到這段空間中

  3. 對非靜態成員變數進行預設初始化(基本資料型別賦值為預設值,引用型別為null)

  4. 然後呼叫建構函式

  5. 在建構函式函式體執行之前先隱式的執行如下幾個步驟

     1.如果建構函式沒有顯示的調動父類的建構函式時會預設呼叫super();呼叫父類的無參構造方法
    
     2.對非靜態成員進行顯式初始化(即初始化為我們程式所給的值)
    
     3,執行構造程式碼塊(形如{......})
    
  6. 執行建構函式中的程式碼

  7. 將物件堆的地址賦值給棧中的obj,由此obj指向堆中的Object物件的實體

值得注意的是:

  1. 當使用類字面常量來生成Class物件即Object.class時並不會自動執行Class物件的初始化。
  2. 當訪問一個類的編譯期常量(static final 名字)時並不會觸發對類的初始化
  3. 當使用Class.forName(類的完全限定名)時一定會立刻觸發類的初始化