天天看點

Java類的初始化順序

做Java開發的,起碼要知道類的初始化順序,因為這樣你才知道編寫的代碼運作到了那裡。

Java類的初始化順序
與文無關

一段代碼

public class BaseTest {
    private String baseName = "baseName";


    static {
        System.out.println("父類靜态代碼塊");
    }



    public BaseTest() {
        System.out.println("父類構造方法");
        callName();
    }

    public void callName(){
        System.out.println(baseName);
    }

    static class Sub extends BaseTest{
        private String baseName = "subName";

        public Sub() {
            System.out.println("子類構造方法");
        }

        static {
            System.out.println("子類靜态代碼塊");
        }

        @Override
        public void callName() {
            System.out.println(baseName);   //輸出為null
            super.callName();   //輸出baseName,baseStatic
        }

    }

    public static void main(String[] args) {
        Sub sub = new Sub();
    }

}


           

以上代碼運作的結果如下:

父類靜态代碼塊
子類靜态代碼塊
父類構造方法
null
baseName
子類構造方法
           

為什麼在子類中直接調用 System.out.println(baseName),輸出為null呢?

在創造派生類的過程中首先建立基類對象,然後才能建立派生類。建立基類即預設調用BaseTest()方法,在方法中調用callName()方法,由于派生類中存在此方法,則被調用的callName()方法是派生類中的方法,此時派生類還未構造,是以變量baseName的值為null

靜态代碼塊的初始化

public class StaticTest {

    static {
        System.out.println("父類的靜态代碼塊");
    }

    public static String str = getStr();

    private static String getStr() {
        System.out.println("父類的靜态方法");
        return "str1";
    }

    public StaticTest() {
        System.out.println("父類構造方法");
    }

    static class SubStatic extends StaticTest{
        static {
            System.out.println("子類的靜态代碼塊");
        }

        public static String str1 = getStr1();

        private static String getStr1() {
            System.out.println("子類的靜态方法");
            return "str1";
        }

        public SubStatic() {
            System.out.println("子類構造方法");
        }
    }

    public static void main(String[] args) {
        new SubStatic();
    }
}
           

運作結果:

父類的靜态代碼塊
父類的靜态方法
子類的靜态代碼塊
子類的靜态方法
父類構造方法
子類構造方法
           

最後

動手操作,檢視了下類的初始化過程。