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

Java ArrayList get() 返回引用為何修改不影響原元素:String 不可變性深度解析

     編輯:程式設計疑難解答

現象重現

List<String> list = new ArrayList<>();
list.add("abc");
String str = list.get(0); // 獲取引用
str += "def";             // 修改引用指向的對象?
System.out.println(str);  // abcdef
System.out.println(list); // [abc] ← 原元素未變!

核心原因:String 是不可變對象

  1. list.get(0) 返回字串 "abc" 的**引用** (地址),str 指向堆中 "abc" 對象。
  2. str += "def" 編譯器轉為 str = str + "def" → new StringBuilder().append(str).append("def").toString()。
  3. **產生全新字串對象 "abcdef"** 在堆中,str 引用指向新對象。
  4. 原 "abc" 對象**未被修改**,List 仍引用舊對象。

對比:可變對象 (如 StringBuilder) 行為不同

List<StringBuilder> list = new ArrayList<>();
list.add(new StringBuilder("abc"));
StringBuilder sb = list.get(0);
sb.append("def"); // 直接修改對象內部字元陣列
System.out.println(sb);  // abcdef
System.out.println(list); // [abcdef] ← 原元素也變了!

記憶體圖解

修改前:
str ──────► "abc" ◄────── list[0]

str += "def" 後:
str ──────► "abcdef"   (新對象)
list[0] ──► "abc"      (舊對象不變)

總結

  • get() 確實返回**引用** (地址傳遞)。
  • **不可變類 (String, Integer, Long 等包裝類)** 任何「修改」操作實為**建立新對象**,原引用不變。
  • **可變類 (StringBuilder, ArrayList, 自定義 Bean)** 通過引用調用修改方法會影響原對象。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved