Java 之初始化順序

0 前言

本文通過拆分類似概念之間的初始化順序,幫助大家徹底記住初始化的順序

1. 父類和子類間的初始化順序

示例代碼:

public class Father {
    public Father() {
        System.out.println("father");
    }

    public static void main(String[] args) {
        grandson grandson = new grandson();
    }
}
class son extends Father {
    public son() {
        System.out.println("son");
    }
}
class grandson extends son{
    public grandson() {
        System.out.println("grandson");
    }
}

輸出結果:

father
son
grandson

結論:
當存在父類時,先初始化父類構造函數,如果父類還有父類,再初始父類的父類構造函數,依次類推。

2. 構造函數、靜態變量和實例變量的初始化順序

示例代碼:

public class Var {
    public Var() {
        printInit("structor");
    }
    public int j = printInit("Init");

    public static int i = printInit("static Init");

    static int printInit(String s) {
        System.out.println(s);
        return 0;
    }

    public static void main(String[] args) {
        Var var = new Var();
    }
}

輸出結果:

static Init
Init
structor

結論:
靜態變量 -> 實例變量 -> 結構體

3. 靜態語句塊和靜態變量的初始化順序

示例代碼:

public class StaticCompare {

    public static int i = 1;

    static {
        i = 2;
        j = 2;
    }

    public static int j = 1;

    public static void main(String[] args) {
        System.out.println("i = " + StaticCompare.i);
        System.out.println("j = " + StaticCompare.j);
    }

}

輸出結果:

i = 2
j = 1

結論:
靜態語句塊和靜態變量按代碼順序執行,誰在前面誰先執行

4. 普通語句塊和實例變量的初始化順序

示例代碼:

public class VarCompare {
    public int i = 1;

    {
        i = 2;
        j = 2;
    }

    public int j = 1;

    public static void main(String[] args) {
        VarCompare varCompare = new VarCompare();
        System.out.println("i = " + varCompare.i);
        System.out.println("j = " + varCompare.j);
    }
}

輸出結果:

i = 2
j = 1

結論:
普通語句塊和實例變量按代碼順序執行,誰在前面誰先執行

5. 總結

先做個小結,現在已經測試的順序是:
靜態變量(靜態語句塊) -> 實例變量(普通語句塊) -> 構造函數
父類構造函數 -> 子類構造函數
接下來需要知道的是,當它們同時存在,是什麼順序?

5. 全部的初始化順序

示例代碼:

public class AllSequence extends father{
    public static int i = printInit("子類靜態變量 i");

    public int j = printInit("子類實例變量 j");

    AllSequence(){
        System.out.println("子類構造函數");
    }

    public static void main(String[] args) {
        AllSequence allSequence = new AllSequence();
    }
}

class father {
    public static int i = printInit("父類靜態變量 i");

    public int j = printInit("父類實例變量 j");

    father(){
        System.out.println("父類構造函數");
    }

    static int printInit(String s) {
        System.out.println(s);
        return 1;
    }
}

輸出結果:

父類靜態變量 i
子類靜態變量 i
父類實例變量 j
父類構造函數
子類實例變量 j
子類構造函數

結論:
當存在繼承關係時,初始化順序爲:

  1. 父類(靜態變量、靜態語句塊)
  2. 子類(靜態變量、靜態語句塊)
  3. 父類(實例變量、普通語句塊)
  4. 父類(構造函數)
  5. 子類(實例變量、普通語句塊)
  6. 子類(構造函數)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章