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

Java String 與 StringBuffer 深度解析:不可變與可變字串的效能差異

     編輯:Java 程式設計入門

核心差異總覽

特性StringStringBuffer
可變性不可變(final 類別)可變(線程安全)
連接操作每次產生新物件內部緩衝區擴展,避免新建
執行緒安全不可變天生安全方法加 synchronized
效能(大量連接)極差,O(n²) 字元複製優異,摊銷 O(1)
適用場景常量、少量連接、多執行緒共享大量字串構建、單執行緒首選 StringBuilder

為什麼 String 連接效率低?

str += "abc" 編譯器實際轉換為:

StringBuilder sb = new StringBuilder(str);
sb.append("abc");
str = sb.toString();

每次連接都建立新 StringBuilder、複製字元陣列、產生新 String,舊物件變垃圾需 GC。循環 5000 次連接 26 字母,String 耗時 ~46 秒,StringBuffer 僅 ~16 毫秒(差距超過 2000 倍)。

程式碼驗證

public class StringPerfTest {
    public static void main(String[] args) {
        String base = "abcdefghijklmnopqrstuvwxyz";
        int times = 5000;

        long t1 = System.currentTimeMillis();
        String s = "";
        for (int i = 0; i < times; i++) s += base;
        System.out.println("String += : " + (System.currentTimeMillis() - t1) + " ms");

        long t2 = System.currentTimeMillis();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < times; i++) sb.append(base);
        System.out.println("StringBuffer.append: " + (System.currentTimeMillis() - t2) + " ms");
    }
}

典型輸出:

String += : 46000 ms
StringBuffer.append: 16 ms

StringBuilder(Java 5+)

  • API 與 StringBuffer 相同,但非線程安全(無 synchronized)。
  • 單執行緒環境下效能更高,建議優先使用。
  • 編譯器優化 + 操作符時實際使用 StringBuilder。

檔案複製實例對比

// 使用 String 累積(極慢,記憶體暴增)
String content = "";
while ((len = in.read(buf)) != -1) content += new String(buf, 0, len);

// 使用 StringBuffer(快,記憶體穩定)
StringBuffer sb = new StringBuffer();
while ((len = in.read(buf)) != -1) sb.append(new String(buf, 0, len));
writer.write(sb.toString().toCharArray());

最佳實踐建議

  1. 單執行緒構建字串:StringBuilder sb = new StringBuilder(); sb.append(...); String result = sb.toString();
  2. 多執行緒共享緩衝區:StringBuffer 或 ThreadLocal。
  3. 常量字串:直接用 String,編譯期常量摺疊自動優化。
  4. 格式化輸出:String.format()、MessageFormat、StringBuilder 組合。
  5. 避免循環中使用 +:改用 StringBuilder 或 Collectors.joining() (Stream API)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved