首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Java 類加載與初始化順序深度解析:阿里筆試題完整演示

     編輯:程式設計綜合問答

題目代碼

public class Alibaba {
    public static int k = 0;
    public static Alibaba t1 = new Alibaba("t1");
    public static Alibaba t2 = new Alibaba("t2");
    public static int i = print("i");
    public static int n = 99;
    private int a = 0;
    public int j = print("j");
    { print("構造塊"); }
    static { print("靜態塊"); }
    public Alibaba(String str) {
        System.out.println((++k) + ":" + str + " i=" + i + " n=" + n);
        ++i; ++n;
    }
    public static int print(String str) {
        System.out.println((++k) + ":" + str + " i=" + i + " n=" + n);
        ++n; return ++i;
    }
    public static void main(String[] args) {
        Alibaba t = new Alibaba("init");
    }
}

輸出結果

1:j i=0 n=0
2:構造塊 i=1 n=1
3:t1 i=2 n=2
4:j i=3 n=3
5:構造塊 i=4 n=4
6:t2 i=5 n=5
7:i i=6 n=6
8:靜態塊 i=7 n=99
9:j i=8 n=100
10:構造塊 i=9 n=101
11:init i=10 n=102

執行順序三階段模型

第一梯隊:靜態成員(類加載階段)

按源碼順序依次執行:

  1. k = 0(默認值)
  2. t1 = new Alibaba("t1") → 觸發實例初始化(見第二梯隊) → 構造器打印第 3 行
  3. t2 = new Alibaba("t2") → 同理打印第 6 行
  4. i = print("i") → 打印第 7 行,返回 7,i=7
  5. n = 99(顯式賦值覆蓋前面累加的 n)
  6. static { print("靜態塊"); } → 打印第 8 行,注意此時 n=99

第二梯隊:實例成員(對象創建時)

每次 new Alibaba(...) 依序執行:

  1. 實例變量賦值:a=0、j = print("j") → 打印第 1、4、9 行
  2. 實例初始化塊:{ print("構造塊"); } → 打印第 2、5、10 行
  3. 構造器主體:打印對應行

第三梯隊:main 方法執行

new Alibaba("init") 再次走完第二梯隊,產生第 9-11 行。

關鍵陷阱總結

  • 靜態字段中 new 自身類:會提前觸發實例初始化,導致靜態字段 i、n 尚未賦值(仍為默認值 0)。
  • 靜態塊執行時 n 已為 99:因顯式賦值 n=99 在靜態塊之前。
  • print 方法副作用:修改靜態變量 i、n、k,導致後續讀取值發生變化。

通用記憶口訣

父靜態 → 子靜態 → 父實例 → 父構造 → 子實例 → 子構造
同類內:靜態按順序 → 實例按順序 → 構造器

實戰建議

  1. 避免在靜態字段初始化中創建自身實例(單例模式除外,且需雙重檢查鎖)。
  2. 靜態變量盡量不依賴其他靜態方法的副作用。
  3. 使用 static final 常量替代可變靜態字段,降低認知負荷。
  4. 單元測試覆蓋類加載邏輯,確保多線程環境下初始化安全。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved