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

Java 字符串三大核心類:String、StringBuffer、StringBuilder 深度對比與選型指南

     編輯:程式設計綜合問答

核心定位

類可變性線程安全繼承關係適用場景
String不可變天然安全final class常量、鍵值、少量拼接
StringBuffer可變同步方法 (synchronized)final class多線程頻繁修改 (較少用)
StringBuilder可變非線程安全final class單線程高效拼接 (首選)

底層實現差異

  • String:private final char value[] (Java 9+ byte[] + coder),任何修改操作 (concat, replace, substring) 都創建新陣列、新物件。
  • StringBuffer/Builder:繼承 AbstractStringBuilder,內部 char[] value 可擴容 (預設 16 字符,擴容 2倍+2)。append 直接寫入陣列,toString() 才創建新 String (Java 9+ 共用陣列)。

效能實測 (JMH 基準,10 萬次拼接)

Benchmark                     Mode  Cnt     Score    Error  Units
StringConcat                 thrpt   5    12.3 ±  0.5  ops/s  // 極慢
StringBufferAppend           thrpt   5  1850.2 ± 12.3  ops/s
StringBuilderAppend          thrpt   5  2100.7 ± 15.1  ops/s  // 最快

StringBuilder 比 StringBuffer 快 ~10-15%(無鎖開銷)。

常見操作對比


// String
String s = "hello";
s += " world"; // 實際:new StringBuilder().append("hello").append(" world").toString()

// StringBuffer
StringBuffer sb = new StringBuffer();
sb.append("hello"); // 同步鎖
sb.append(" world");

// StringBuilder (推薦)
StringBuilder sbd = new StringBuilder();
sbd.append("hello");
sbd.append(" world");
String result = sbd.toString();

// 鏈式調用
new StringBuilder().append("a").append("b").insert(1, "c").delete(0,1).reverse().toString();

進階特性

容量預分配


StringBuilder sb = new StringBuilder(1024); // 避免多次擴容複製
sb.ensureCapacity(2048); // 手動擴容

Java 9+ 緊湊字符串

  • String 內部改用 byte[] + byte coder (LATIN1/UTF16),純 ASCII 節省 50% 記憶體。
  • StringBuilder 仍用 char[],toString() 會根據內容決定編碼。

序列化與 JSON

  • Jackson/Gson 直接序列化 StringBuilder 為字符串(調用 toString())。
  • 避免在實體類直接暴露 StringBuilder 欄位,建議轉換為 String。

選型決策樹

需要頻繁修改字符串?
├─ 否 → 直接用 String
└─ 是 → 多線程環境?
         ├─ 是 → StringBuffer (或 ThreadLocal)
         └─ 否 → StringBuilder (預設容量優化)

避坑指南

  1. String s = null; s += "a"; → "nella" (字面量 "null"),非空指針異常。
  2. 循環中 s += i 每次創建 StringBuilder,改用外部單一實例。
  3. StringBuilder 非線程安全,勿作為共享欄位或靜態變量無鎖訪問。
  4. substring (Java 7-) 共用底層陣列可能導致記憶體洩漏,大字符串切片用 new String(s.substring(...)) 強制複製。

最佳實踐

  1. 默認選 StringBuilder,構造函數預估容量。
  2. 方法參數/返回值優先用 String,內部實現用 StringBuilder。
  3. 日誌框架 (SLF4J/Log4j2) 使用佔位符 "{} {}" 避免無效拼接。
  4. 正則分割/替換大文本考慮 Matcher.appendReplacement/Tail 直接寫入 StringBuilder。

記住:String 是「值」,StringBuilder 是「建造者」,StringBuffer 是「帶鎖的建造者」。

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