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

Java List.add() 添加對象卻全變成最後一個?static 靜態字段導致的引用共享陷阱

     編輯:程式設計綜合問答

問題現場

public class Listaa {
    private static List list = new ArrayList();
    private static int i;  // ← 關鍵:static 靜態字段!

    public static void maain(int i) {
        Listaa t = new Listaa();
        t.setI(i);
        list.add(t);
    }

    public static void main(String[] args) {
        for (int i = 0; i < 3; i++) maain(i);
        for (int i = 0; i < list.size(); i++) {
            Listaa a = (Listaa) list.get(i);
            System.out.println(a.getI());  // 輸出:2 2 2  (預期 0 1 2)
        }
    }
    // getter/setter 省略
}

根因分析:static 字段屬於類,不屬於實例

private static int i 導致:

  1. 所有 Listaa 實例**共享同一個** i 字段(內存中只有一份)。
  2. 循環調用 maain(0)、maain(1)、maain(2) 時,每次 t.setI(i) 都在**覆蓋同一個靜態變量**。
  3. 最終 i = 2,列表中三個引用指向的對象雖不同,但其 i 字段指向同一記憶體地址,讀取時全為 2。

內存圖解

Heap:
+------------------+
| Listaa@1 | i →  |──┐
+------------------+  │
| Listaa@2 | i →  |──┤  同一地址
+------------------+  │
| Listaa@3 | i →  |──┘
+------------------+
      Static Area:
      int i = 2  (最終值)

修正方案:移除 static,改為實例字段

public class Listaa {
    private List<Listaa> list = new ArrayList<>();  // 也建議改為實例字段
    private int i;  // ← 非 static,每個對象擁有獨立副本

    public void maain(int i) {
        Listaa t = new Listaa();
        t.setI(i);
        list.add(t);
    }

    public static void main(String[] args) {
        Listaa app = new Listaa();
        for (int i = 0; i < 3; i++) app.maain(i);
        for (Listaa a : app.list) {
            System.out.println(a.getI());  // 正確輸出:0 1 2
        }
    }
    // getter/setter
}

延伸避坑指南

錯誤模式後果修正
集合字段聲明 static所有實例共享同一列表,數據串聯改為實例字段,或傳入外部列表
循環中重用同一對象引用List.add(obj) 多次添加同一引用循環內 new Object() 創建新實例
匿名內部類捕獲循環變量閉包引用同一變量,最終值一致引入 final 局部變量副本

總結

static 字段是類級別的單一存儲槽。將本應屬於對象狀態的數據誤標為 static,會導致所有實例共享同一值,這是 Java 新手最經典的「引用共享」Bug。記住:實例數據 → 實例字段;類級別常量/工具 → static final。

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