1. 程式人生 >實用技巧 >其它 >類繼承鏈上的初始化(屬性和靜態程式碼塊的執行順序)

類繼承鏈上的初始化(屬性和靜態程式碼塊的執行順序)


技術標籤:筆記java多型面試

類的初始化順序

類的初始化:在類連結的準備階段時,類屬性會被賦予預設值;類連結階段之後,類屬性賦值和靜態程式碼塊才會被執行(類初始化)。

現在探究 類繼承鏈上的類屬性賦值和靜態程式碼塊的執行順序 ?

預期瞭解

  1. 初始化順序,靜態程式碼塊和靜態屬性(按自上而下的排列順序);
  2. 如果父類沒有被初始化,就會先初始化父類,初始化完父類,才會輪到自己;

注:

  1. 由 final 修飾的靜態屬性,只有使用 new 關鍵字賦值, 才會觸發類的初始化(只是屬性特例,方法沒影響)
// new 關鍵字 觸發 類的初始化
static final Object obj = new Object();
// 不觸發 類的初始化
static final int count = 1;
  1. 靜態內部類的初始化 不會 觸發外部類的初始化

測試

注:測試類 必須另外 建立,因為 JVM 會首先載入和初始化 主類(有 main 方法的類)

public class Children extends Parent{
    // 靜態程式碼塊
    static {
        System.out.println("初始化子類的靜態程式碼塊");
    }
    // 普通靜態屬性
    public static Option2 option = new Option2();
    // final 靜態屬性
    // 使用 new 關鍵字
    public static final Object newFinalObj = new Object();
    // 不是用 new 關鍵字
    public static final int finalCount = 1;
    // 普通靜態方法
    public static String test1(){
        System.out.println("呼叫子類的 普通靜態方法");
        return "";
    }
    // final 靜態方法
    public static final String finalMethod(){
        System.out.println("呼叫子類的 final的靜態方法");
        return "";
    }

    static class StaticInClass{
        public static Option1 option = new Option1();
        // final 靜態屬性
        // 使用 new 關鍵字
        public static final Object newFinalObj = new Object();
        // 不是用 new 關鍵字
        public static final int finalCount = 1;
        // 靜態程式碼塊
        static {
            System.out.println("初始化子類的靜態內部類的靜態程式碼塊");
        }
        // 普通靜態方法
        public static String test1(){
            System.out.println("呼叫子類的靜態內部類的 普通靜態方法");
            return "";
        }
        // final 靜態方法
        public static final String finalMethod(){
            System.out.println("呼叫子類的靜態內部類的 final的靜態方法");
            return "";
        }
    }
}
class Option1{
    static {
        System.out.println("初始化子類的靜態內部類的靜態屬性");
    }
}
class Option2{
    static {
        System.out.println("初始化子類的靜態屬性");
    }
}

public class Parent {
    // 靜態程式碼塊
    static {
        System.out.println("初始化父類的靜態程式碼塊");
    }
    // 普通靜態屬性
    public static Option0 option = new Option0();
    // final 靜態屬性
    // 使用 new 關鍵字
    public static final Object newFinalObj = new Object();
    // 不是用 new 關鍵字
    public static final int finalCount = 1;
    // 普通靜態方法
    public static String test1(){
        System.out.println("呼叫父類的 普通靜態方法");
        return "";
    }
    // final 靜態方法
    public static final String finalMethod0(){
        System.out.println("呼叫父類的 final的靜態方法");
        return "";
    }
}
class Option0{
    static {
        System.out.println("初始化父類的靜態屬性");
    }
}
public class Test {
    public static void main(String[] args) {
        // 測試本類
        // System.out.println(Children.option);
        // System.out.println(Children.newFinalObj);
        // System.out.println(Children.finalCount);
        // System.out.println(Children.finalMethod());
        // System.out.println(Children.test1());

        // 測試靜態內部類
        // System.out.println(Children.StaticInClass.option);
        // System.out.println(Children.StaticInClass.finalCount);
        // System.out.println(Children.StaticInClass.newFinalObj);
        // System.out.println(Children.StaticInClass.finalMethod());
        // System.out.println(Children.StaticInClass.test1());

        // 測試 繼承鏈的
        // System.out.println(Children.newFinalObj);
    }
}

結論

和預期瞭解吻合。。。