| 特性 | String | StringBuffer | StringBuilder |
|---|---|---|---|
| 可變性 | 不可變 | 可變 | 可變 |
| 線程安全 | ✅ (不可變天然安全) | ✅ (方法 synchronized) | ❌ (非線程安全) |
| 性能 | 拼接慢(產生新對象) | 中等(同步開銷) | 最快(無同步) |
| 繼承關係 | final class | extends AbstractStringBuilder | extends AbstractStringBuilder |
| JDK 版本 | 1.0 | 1.0 | 5.0 |
String s = "abc":檢查字符串池,有則返回引用,無則創建並入池。new String("abc"):強制在堆創建新對象,不入池(除非調用 intern())。"" vs null vs new String():null 無引用無內存;"" 和 new String() 有對象頭+空 char 數組,佔用內存。| 操作 | String | StringBuffer/Builder |
|---|---|---|
| 比較 | equals(), compareTo(), equalsIgnoreCase() | 轉 String 後比較 |
| 查找 | indexOf(), lastIndexOf(), startsWith(), endsWith() | indexOf() 等同樣方法 |
| 截取 | substring() | substring() |
| 替換 | replace(), replaceAll(regex) | 無直接替換,需轉 String |
| 拼接/追加 | +、concat() | append() |
| 插入/刪除 | 無(需轉 StringBuilder) | insert(), delete() |
public class ConcatBenchmark {
public static void main(String[] args) {
int N = 100_000;
// 1. + 操作符
long t1 = System.currentTimeMillis();
String s1 = "a";
for (int i = 0; i < N; i++) s1 += "b";
System.out.println("+ 操作符: " + (System.currentTimeMillis() - t1) + " ms");
// 2. concat()
long t2 = System.currentTimeMillis();
String s2 = "c";
for (int i = 0; i < N; i++) s2 = s2.concat("d");
System.out.println("concat(): " + (System.currentTimeMillis() - t2) + " ms");
// 3. StringBuilder.append()
long t3 = System.currentTimeMillis();
StringBuilder sb = new StringBuilder("e");
for (int i = 0; i < N; i++) sb.append("d");
System.out.println("StringBuilder.append(): " + (System.currentTimeMillis() - t3) + " ms");
}
}
典型輸出:
+ 操作符: 19080 ms
concat(): 9089 ms
StringBuilder.append(): 10 ms
編譯器優化:s += "b" → new StringBuilder(s).append("b").toString()。每次循環創建新 StringBuilder + toString() 新 String,10 萬次對象分配極其昂貴。
內部複製 char 數組並 new String(),同樣創建 10 萬個 String 對象。
擴容 char 數組,System.arraycopy 複製內容,全程複用同一對象,零新對象分配。
String s = "I " + "am " + "chenssy"; // 編譯期常量折疊 → "I am chenssy"
String s2 = "I " + name + " chenssy"; // 運行期 → StringBuilder
純字面量拼接編譯期直接合併,極快;含變量則退化為 StringBuilder。
| 場景 | 推薦類 | 理由 |
|---|---|---|
| 常量、少量拼接、鍵值對 | String | 語義清晰、JVM 優化、不可變安全 |
| 多線程環境下頻繁拼接/修改 | StringBuffer | 線程安全、XML/HTTP 參數構建 |
| 單線程/局部變量頻繁拼接 | StringBuilder | 最高效、SQL 拼裝、JSON 構建、日誌拼接 |
最佳實踐: 局部變量拼接優先
StringBuilder;多線程共享緩衝區用StringBuffer;API 返回值、常量、鍵用String。別過早優化,但寫熱路徑時請選對工具。