天天看點

Java之類。執行個體初始化

類被加載記憶體後,會在方法區建立一個Class對象(後面反射章節詳細學習)來存儲該類的所有資訊。此時會為類的靜态變量配置設定記憶體,然後為類變量進行初始化。那麼,實際上,類初始化的過程時在調用一個<clinit>()方法,而這個方法是編譯器自動生成的。編譯器會将如下兩部分的所有代碼,按順序合并到類初始化<clinit>()方法體中。

(1)靜态類成員變量的顯式指派語句

(2)靜态代碼塊中的語句

整個類初始化隻會進行一次,如果子類初始化時,發現父類沒有初始化,那麼會先初始化父類。

Java之類。執行個體初始化
Java之類。執行個體初始化

View Code

父子類

Java之類。執行個體初始化
Java之類。執行個體初始化

結論:

每一個類都有一個類初始化方法<clinit>()方法,然後子類初始化時,如果發現父類加載和沒有初始化,會先加載和初始化父類,然後再加載和初始化子類。一個類,隻會初始化一次。

文法格式:在類中方法外,一個類中可以出現多個

實際上我們編寫的代碼在編譯時,會自動處理代碼,整理出一個<clinit>()的類初始化方法,還會整理出一個或多個的<init>(...)執行個體初始化方法。一個類有幾個執行個體初始化方法,由這個類有幾個構造器決定。

執行個體初始化方法的方法體,由四部分構成:

(1)super()或super(實參清單) 這裡選擇哪個,看原來構造器首行是哪句,沒寫,預設就是super()

(2)非靜态執行個體變量的顯示指派語句

(3)非靜态代碼塊

(4)對應構造器中的代碼

特别說明:其中(2)和(3)是按順序合并的,(1)一定在最前面(4)一定在最後面

執行特點:

建立對象時,才會執行,

調用哪個構造器,就是指定它對應的執行個體初始化方法

建立子類對象時,父類對應的執行個體初始化會被先執行,執行父類哪個執行個體初始化方法,看用super()還是super(實參清單)

Java之類。執行個體初始化
Java之類。執行個體初始化

 

類初始化肯定優先于執行個體初始化。

類初始化隻做一次。

執行個體初始化是每次建立對象都要進行。

從某種程度上來看,非靜态代碼塊是對構造器的補充,非靜态代碼塊總是在構造器執行之前執行。與構造器不同的是,非靜态代碼塊是一段固定執行的代碼,它不能接收任何參數。是以非靜态代碼塊對同一個類的所有對象所進行的初始化處理完全相同。基于這個原因,不難發現非靜态代碼塊的基本用法,如果有一段初始化處理代碼對所有對象完全相同,且無須接收任何參數,就可以把這段初始化處理代碼提取到非靜态代碼塊中。

即如果每個構造器中有相同的初始化代碼,且這些初始化代碼無須接收參數,就可以把它們放在非靜态代碼塊中定義。通過把多個構造器中相同代碼提取到非靜态代碼塊中定義,能更好地提高初始代碼的複用,提高整個應用的可維護性。