天天看點

靜态代碼塊、靜态成員變量、普通代碼塊、普通成員變量、構造方法加載次序

一.結論:

父類靜态代碼塊,父類靜态成員變量》》子類的靜态代碼塊、子類的靜态變量》》父類的普通代碼塊,父類普通成員變量,父類構造方法》》子類的普通代碼塊、子類普通成員變量、子類的構造方法

二、觸發時間

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虛拟機》