一.結論:
父類靜态代碼塊,父類靜态成員變量》》子類的靜态代碼塊、子類的靜态變量》》父類的普通代碼塊,父類普通成員變量,父類構造方法》》子類的普通代碼塊、子類普通成員變量、子類的構造方法
二、觸發時間
1、靜态代碼塊,靜态成員變量:在類加載的時候被加載,比如在new時候會觸發,通過類調用靜态方法 或者靜态變量,Class.forName
2、普通代碼塊、普通成員變量、構造方法:在每次執行個體化的時候被加載 比如new,invoke
三、代碼
1.建構一個Father類
public class Father {
static{
System.out.println("father 靜态代碼塊");
}
{
System.out.println("father 普通代碼塊");
}
public Father(){
System.out.println("父類 構造方法");
}
}
2.建構一個Son類
public class Son extends Father {
static{
System.out.println("Son 靜态代碼塊");
}
public static GrandSon grandSon= new GrandSon();
{
System.out.println("Son普通代碼塊");
}
public Son(){
System.out.println("Son 構造方法");
}
public static void get(){
}
}
3.建構一個GrandSon類
public class GrandSon {
static{
System.out.println("GrandSon 靜态代碼塊");
}
{
System.out.println("GrandSon 普通代碼塊");
}
public GrandSon(){
System.out.println("GrandSon 構造方法");
}
}
4.建立一個Test測試類
(1)new 建立執行個體
public class TestOrder {
public static void main(String[] args) throws ClassNotFoundException {
//類加載的兩種常見方式:1,通過執行個體化(new、反射、class.forName) 2.通過調用靜态的方法或者靜态變量
new Son(); //會加載 父類的靜态代碼塊》子類靜态代碼快》父類的非靜态代碼快、父類的構造方法》子類的非靜态代碼塊、子類的構造方法
// Son.get();//知會加載父類的靜态代碼塊》子類的靜态代碼塊
// Class.forName("com.example.order.Son");
}
}
結果
(2)通過類調用靜态方法
public class TestOrder {
public static void main(String[] args) throws ClassNotFoundException {
//類加載的兩種常見方式:1,通過執行個體化(new、反射、class.forName) 2.通過調用靜态的方法或者靜态變量
// new Son(); //會加載 父類的靜态代碼塊》子類靜态代碼快》父類的非靜态代碼快、父類的構造方法》子類的非靜态代碼塊、子類的構造方法
Son.get();//知會加載父類的靜态代碼塊》子類的靜态代碼塊
// Class.forName("com.example.order.Son");
}
}
結果
(3)通過Class.forName
public class TestOrder {
public static void main(String[] args) throws ClassNotFoundException {
//類加載的兩種常見方式:1,通過執行個體化(new、反射、class.forName) 2.通過調用靜态的方法或者靜态變量
// new Son(); //會加載 父類的靜态代碼塊》子類靜态代碼快》父類的非靜态代碼快、父類的構造方法》子類的非靜态代碼塊、子類的構造方法
// Son.get();//知會加載父類的靜态代碼塊》子類的靜态代碼塊
Class.forName("com.example.order.Son");
}
}
結果
四、理論分析
類的加載機制主要分為三步驟:
加載、連接配接、初始化
在加載中會将class中的靜态結構轉化為JVM中運作時資料區的對象,并完成檢驗與初始化
具體理論後續待看完周志明的《深入了解java虛拟機》