| 類 | 可變性 | 線程安全 | 繼承關係 | 適用場景 |
|---|---|---|---|---|
| String | 不可變 | 天然安全 | final class | 常量、鍵值、少量拼接 |
| StringBuffer | 可變 | 同步方法 (synchronized) | final class | 多線程頻繁修改 (較少用) |
| StringBuilder | 可變 | 非線程安全 | final class | 單線程高效拼接 (首選) |
private final char value[] (Java 9+ byte[] + coder),任何修改操作 (concat, replace, substring) 都創建新陣列、新物件。AbstractStringBuilder,內部 char[] value 可擴容 (預設 16 字符,擴容 2倍+2)。append 直接寫入陣列,toString() 才創建新 String (Java 9+ 共用陣列)。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); // 手動擴容
byte[] + byte coder (LATIN1/UTF16),純 ASCII 節省 50% 記憶體。StringBuilder 仍用 char[],toString() 會根據內容決定編碼。StringBuilder 為字符串(調用 toString())。StringBuilder 欄位,建議轉換為 String。
需要頻繁修改字符串?
├─ 否 → 直接用 String
└─ 是 → 多線程環境?
├─ 是 → StringBuffer (或 ThreadLocal)
└─ 否 → StringBuilder (預設容量優化)
String s = null; s += "a"; → "nella" (字面量 "null"),非空指針異常。s += i 每次創建 StringBuilder,改用外部單一實例。StringBuilder 非線程安全,勿作為共享欄位或靜態變量無鎖訪問。substring (Java 7-) 共用底層陣列可能導致記憶體洩漏,大字符串切片用 new String(s.substring(...)) 強制複製。StringBuilder,構造函數預估容量。String,內部實現用 StringBuilder。"{} {}" 避免無效拼接。Matcher.appendReplacement/Tail 直接寫入 StringBuilder。記住:String 是「值」,StringBuilder 是「建造者」,StringBuffer 是「帶鎖的建造者」。