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); } }

結論

和預期瞭解吻合。。。