一文讓你徹底搞懂Java程序的初始化順序

使用場景

在Java程序中,當實例化對象時,對象的所在類的所有成員變量首先要進行初始化,只有當所有類成員完成初始化後,纔會調用對象所在類的構造函數創建對象。

原則

  1. 變量優先於塊、靜態優先於非靜態。
  2. 父類優先於派生類初始化。
  3. 按照成員變量定義的順序來進行初始化,即使變量定義散佈於方法定義之中,它們仍然在任何方法(包括構造器)被調用前初始化。

初始化順序

  • 父類靜態變量
  • 父類靜態代碼塊
  • 子類靜態變量
  • 子類靜態代碼塊
  • 父類非靜態變量
  • 父類非靜態代碼塊
  • 父類構造函數
  • 子類非靜態變量
  • 子類非靜態代碼塊
  • 子類構造函數

初始化示例代碼


class Base {

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

    String b = "父類非靜態變量";
    {
        System.out.println(b);
        System.out.println("父類非靜態代碼塊");
    }

    static String a = "父類靜態變量";

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

    public static void A() {
        System.out.println("父類普通靜態方法");
    }

}

class Derived extends Base {

    public Derived() {
        System.out.println("子類構造器");
    }

    String b = "子類非靜態變量";
    {
        System.out.println(b);
        System.out.println("子類非靜態代碼塊");
    }

    static String a = "子類靜態變量";

    static {
        System.out.println(a);
        System.out.println("子類靜態塊");
    }

    public static void A() {
        System.out.println("子類普通靜態方法");
    }

    public static void main(String[] args) {
        Base.A();
        Derived.A();
        new Derived();
    }
}

分別執行主函數裏的三條指令,執行結果如下。

Base.A()

  • 父類靜態變量
  • 父類靜態代碼塊
  • 子類靜態變量
  • 子類靜態塊
  • 父類普通靜態方法

Derived.A()

  • 父類靜態變量
  • 父類靜態代碼塊
  • 子類靜態變量
  • 子類靜態塊
  • 子類普通靜態方法

new Derived()

  • 父類靜態變量
  • 父類靜態代碼塊
  • 子類靜態變量
  • 子類靜態代碼塊
  • 父類非靜態變量
  • 父類非靜態代碼塊
  • 父類構造函數
  • 子類非靜態變量
  • 子類非靜態代碼塊
  • 子類構造函數
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章