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

Java 父類與子類初始化順序深度解析

     編輯:Java 程式設計入門

前言

在 Java 物件導向程式設計中,理解類別載入與初始化的順序至關重要,特別是涉及繼承關係時。本文透過完整的程式碼範例與輸出結果,詳細解析父類與子類的靜態/非靜態成員、初始化區塊、建構子的執行順序。

程式碼範例

class Parent {
    // 靜態變數
    public static String p_StaticField = "父類--靜態變量";
    
    // 實例變數
    public String p_Field = "父類--變量";
    
    // 靜態初始化區塊
    static {
        System.out.println(p_StaticField);
        System.out.println("父類--靜態初始化塊");
    }
    
    // 實例初始化區塊
    {
        System.out.println(p_Field);
        System.out.println("父類--初始化塊");
    }
    
    // 建構子
    public Parent() {
        System.out.println("父類--構造器");
    }
}

public class SubClass extends Parent {
    // 靜態變數
    public static String s_StaticField = "子類--靜態變量";
    
    // 實例變數
    public String s_Field = "子類--變量";
    
    // 靜態初始化區塊
    static {
        System.out.println(s_StaticField);
        System.out.println("子類--靜態初始化塊");
    }
    
    // 實例初始化區塊
    {
        System.out.println(s_Field);
        System.out.println("子類--初始化塊");
    }
    
    // 建構子
    public SubClass() {
        // super(); // 隱式呼叫
        System.out.println("子類--構造器");
    }
    
    // 程式進入點
    public static void main(String[] args) {
        System.out.println("*************in main***************");
        new SubClass();
        System.out.println("*************second subClass***************");
        new SubClass();
    }
}

執行結果

父類--靜態變量
父類--靜態初始化塊
子類--靜態變量
子類--靜態初始化塊
*************in main***************
父類--變量
父類--初始化塊
父類--構造器
子類--變量
子類--初始化塊
子類--構造器
*************second subClass***************
父類--變量
父類--初始化塊
父類--構造器
子類--變量
子類--初始化塊
子類--構造器

深度結果分析

類別載入階段(僅執行一次)

當 JVM 首次使用 SubClass 時(此處為 main 方法),會依序載入父類再載入子類:

  1. 父類靜態成員初始化:靜態變數賦值 → 靜態初始化區塊執行
  2. 子類靜態成員初始化:靜態變數賦值 → 靜態初始化區塊執行

這就是為何前四行輸出均為靜態相關內容,且父類優於子類。

物件實例化階段(每次 new 都執行)

每次建立 SubClass 實例時,遵循以下順序:

  1. 父類實例初始化:實例變數賦值 → 實例初始化區塊 → 父類建構子
  2. 子類實例初始化:實例變數賦值 → 實例初始化區塊 → 子類建構子

關鍵機制:隱式 super() 呼叫

子類建構子預設會隱式呼叫 super(),這強制父類建構子優先執行。若父類無無參建構子,子類必須顯式呼叫 super(參數),否則編譯錯誤。

驗證:註解掉 main 方法內容

若 main 方法無建立實例動作,僅輸出靜態初始化部分,證實實例初始化僅在物件建立時觸發。

總結順序表

階段順序說明
類別載入1父類靜態變數與靜態區塊
2子類靜態變數與靜態區塊
物件建立3父類實例變數與實例區塊
4父類建構子
5子類實例變數與實例區塊
6子類建構子

最佳實踐建議

  • 避免在靜態初始化區塊執行複雜邏輯或依賴子類狀態
  • 理解 super() 隱式呼叫機制,設計建構子鏈時需謹慎
  • 靜態成員屬於類別,實例成員屬於物件,切勿混淆生命週期
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved