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

Java 類與物件初始化完整順序詳解:從類載入到實例建立的全流程

     編輯:Java 相關知識

類載入三階段:載入、連結、初始化

JVM 載入類需經歷三大步驟:

  1. 載入:尋找並匯入類的二進位資料。
  2. 連結:包含驗證(檢查位元組碼正確性)、準備(為 static 變數配置記憶體並設預設值)、解析(符號引用轉直接引用,可選)。
  3. 初始化:執行 static 變數賦值語句與 static 區塊,這是類載入的最後一步。

初始化整體順序

類初始化 → 子類建構子 → 父類建構子 → 實例成員變數初始化 → 繼續執行子類建構子語句

一、類初始化

1. 類的初始化

  • 初始化 static field(靜態欄位賦值)。
  • 執行 static initializer(靜態區塊)。
public class Demo {
    private static String str = "initialization static field"; // static field initializer
    static { System.out.println("This is static initializer"); } // static initializer
}

2. 介面的初始化

僅初始化介面中定義的常數(static final 欄位),不會 初始化父介面。

3. 關鍵規則

  • 初始化類時,其父類會遞歸先初始化(一直到 Object),但實現的介面不會初始化。
  • 透過類別引用靜態欄位觸發初始化時,只有真正定義該欄位的類會被初始化。
  • static final 編譯期常數(基本型別或 String)被引用時,不會觸發 定義它的類初始化。

4. 實戰驗證

public class Initialization {
    static { System.out.println("Initialization Main class"); }
    public static void main(String[] args) {
        System.out.println(Sub.y); // 2005
        System.out.println(Sub.x); // 觸發 Super 初始化
        System.out.println(Sub.z); // 觸發 Sub 初始化
    }
}
class Super { public static int x = 2006; static { System.out.println("Initialization Super"); } }
class Sub extends Super { public static final int y = 2005; public static int z; static { System.out.println("Initialization Sub"); } }

輸出:

Initialization Main class 2005 Initialization Super 2006 Initialization Sub 0

解析:Sub.y 為編譯期常數,不觸發初始化;Sub.x 定義於 Super,觸發父類初始化;Sub.z 非常數,觸發 Sub 初始化;static 變數有預設值(z=0)。

二、物件建立

1. 實例建立步驟

  1. 為類及父類所有實例欄位配置記憶體,設預設值(第一次初始化)。
  2. 初始化建構子參數(若有)。
  3. 若用 this() 呼叫本類其他建構子,遞歸執行步驟 2-6。
  4. 若用 super() 呼叫父類建構子,遞歸執行步驟 2-6。
  5. 按宣告順序執行 instance initializer 與 instance variable initializer(第二次初始化)。
  6. 執行建構子剩餘語句。

2. 完整範例

public class InitializationOrder { public static void main(String[] args) { new SubClass(); } }
class SuperClass { static { System.out.println("SuperClass static"); } SuperClass(String str) { System.out.println(str); } }
interface Interface { static SuperClass su = new SuperClass("Interface new SuperClass"); }
class SubClass extends SuperClass implements Interface {
    static { System.out.println("SubClass static"); }
    private SuperClass su = new SuperClass("initialization variable");
    SubClass() { super("super"); new SuperClass("new SuperClass"); }
}

輸出:

SuperClass static SubClass static super initialization variable new SuperClass

解析:介面 Interface 的 static 欄位不會 在實現類初始化時執行,只有直接使用介面時才會初始化。

總結

掌握 類初始化(static 階段) 與 物件建立(實例階段) 的精確順序,特別是父子類交織、介面靜態欄位、編譯期常數等細節,是編寫正確、可預測 Java 程式的關鍵基礎。

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