首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 類初始化執行順序深度解析:靜態塊、實例塊、建構子與繼承鏈

     編輯:Java 相關知識

前言:看不見的初始化舞步

Java 類載入與初始化遵循嚴格規範,但許多開發者只知「main 先跑」,不知靜態塊、實例塊、建構子、父子類之間的精確順序。本文通過層層遞進的代碼實驗,完整還原 JVM 初始化時序,並揭示「無 main 也能跑」的冷知識。

階段一:隱式動作 (源碼看不見)

  1. 無 package → 隱式屬於「無名包」
  2. 自動 import java.lang.* → String、Math、Integer 等直接用
  3. 無 extends → 隱式 extends Object
  4. 欄位預設值初始化 (0、null、false...)

階段二:顯式初始化順序實驗

實驗 1:單一類,無物件建立

public class JRun1 {
    static { System.out.println("static{}"); }
    { System.out.println("{}"); }
    public JRun1() { System.out.println("建構子"); }
    public static void main(String[] args) { System.out.println("main()"); }
}

輸出

static{}
main()

結論:靜態塊 → main()。實例塊、建構子因無 new 不執行。

冷知識:無 main 也能執行

public class NoMain {
    static { System.out.println("no main()"); System.exit(0); }
}

類載入時執行靜態塊,System.exit(0) 正常結束。

實驗 2:main 中建立本類物件

public static void main(String[] args) {
    System.out.println("main()");
    new JRun1();
}

輸出

static{}
main()
{}
建構子

結論:靜態塊 → main → 實例塊 → 建構子。

階段三:繼承鏈初始化鐵律

class Father {
    Father() { System.out.println("父建構子"); }
    static { System.out.println("父靜態塊"); }
    { System.out.println("父實例塊"); }
}

public class Son extends Father {
    Son() { System.out.println("子建構子"); }
    static { System.out.println("子靜態塊"); }
    { System.out.println("子實例塊"); }
    public static void main(String[] args) { new Son(); }
}

輸出

父靜態塊
子靜態塊
父實例塊
父建構子
子實例塊
子建構子

總結:完整初始化順序口訣

父靜態 → 子靜態 → 父實例塊 → 父建構子 → 子實例塊 → 子建構子

關鍵規則:

  • 靜態塊:類載入時執行,父先子後,僅一次
  • 實例塊:每次 new 執行,在建構子之前,父先子後
  • 建構子:super() (隱式/顯式) → 實例塊 → 本建構子碼
  • 實例塊與建構子緊貼執行,不會父子交替

進階陷阱:靜態欄位初始化順序

class Test {
    static int a = 1;
    static { a = 2; }
    static int b = a + 1;  // b = 3
}

靜態欄位與靜態塊按源碼順序執行。

實戰意義

  • 單例模式靜態內部類寫法利用「類載入時機」保證線程安全
  • 靜態塊異常會導致 ExceptionInInitializerError,類永不可用
  • 父類靜態塊拋異常,子類永無法載入
  • 理解順序才能正確設計「註冊中心」、「驅動載入」等靜態初始化邏輯

結語

Java 初始化機制看似簡單,實則暗合 JVM 類載入規範 (JVMS §5.5)。掌握「父靜→子靜→父實→父構→子實→子構」鐵律,不僅能避開面試陷阱,更能在框架設計、靜態資源管理、異常診斷中做出正確判斷。下次見到靜態塊,請敬畏地說一聲:「妳是第一個跑的。」

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved