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

圖解 Java String 不可變性:為什麼拼接會創建新對象?

     編輯:Java 綜合教學

圖解 Java String 不可變性

String 不可變是 Java 基礎中最高頻考點之一。本文通過三張內存圖解,直觀展示字符串賦值、引用傳遞、拼接操作的內存變化,並給出 StringBuilder 高效拼接最佳實踐。

一、聲明字符串字面量

String s = "abcd";

String 字面量內存圖

  • 棧中變量 s 存儲引用,指向堆/常量池中的 "abcd" 對象。

二、引用賦值

String s2 = s;
  • s2 複製引用值,雙雙指向同一 "abcd" 對象。
  • 此時 s == s2 為 true。

三、字符串拼接

s = s.concat("ef");

String 拼接內存圖

  • concat 內部創建 新 String 對象 "abcdef"。
  • s 更新引用指向新對象,原 "abcd" 仍在常量池(若無其他引用則等待 GC)。
  • 結論:所有 String 方法均不修改原對象,而是返回新對象。

四、性能陷阱與最佳實踐

循環拼接字符串會產生大量中間對象,觸發頻繁 GC:

// 反例:O(n²) 創建對象
String result = "";
for (String part : parts) result += part;

正確姿勢:使用 StringBuilder(單線程)或 StringBuffer(線程安全):

public static String readFileToString() throws IOException {
    File file = new File("src/TestRead.java");
    StringBuilder sb = new StringBuilder(1000); // 預估容量避免擴容
    try (BufferedReader br = new BufferedReader(new FileReader(file))) {
        char[] buf = new char[1024];
        int len;
        while ((len = br.read(buf)) != -1) {
            sb.append(buf, 0, len);
        }
    }
    return sb.toString();
}
  • StringBuilder 內部維護可變 char[],擴容策略為 2倍+2,append 為 O(1) 均攤。
  • 預設初始容量 16,大文件建議預估大小構造,減少擴容拷貝。

五、總結

  1. String 一旦創建不可變,所有「修改」操作實為創建新對象。
  2. 字面量駐留常量池,new String() 強制堆分配。
  3. 高頻拼接必須用 StringBuilder,避免 O(n²) 對象創建與 GC 壓力。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved