| 特性 | StringBuffer | StringBuilder |
| 可變性 | 是(內部 char[]/byte[] 擴容) | 是 |
| 線程安全 | 是(方法 synchronized) | 否(無同步) |
| 效能 | 較低(同步開銷) | 高(單執行緒首選) |
| 繼承 | 同父類 AbstractStringBuilder | 同父類 |
| JDK 版本 | 1.0 | 1.5 |
核心差異:同步關鍵字
// StringBuffer
public synchronized StringBuffer append(String str) { ... }
// StringBuilder
public StringBuilder append(String str) { ... } // 無 synchronized
三、效能基準:拼接字串實測
// 1. String + 拼接(循環中極差)
String s = "";
for (int i = 0; i < 100000; i++) s += "a"; // 每次產生新 String + StringBuilder 物件,O(n²)
// 2. StringBuilder(單執行緒最快)
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 100000; i++) sb.append("a"); // O(n)
// 3. StringBuffer(多執行緒共享時)
StringBuffer sbf = new StringBuffer();
// 多執行緒並發 append 安全
結論:單執行緒用 StringBuilder;多執行緒共享緩衝區用 StringBuffer;簡單拼接編譯器優化為 StringBuilder 可直接用 +。
四、面試高頻題深度解析
Q1: 如何比較兩字串?== vs equals()
== 比較引用地址
equals() 比較內容
- 常量池字串
== 可能 true,new String() 一定 false
- 永遠用
equals() 比較內容
Q2: String s = new String("abc") 建立幾個物件?
- 常量池中
"abc"(若不存在則建立)
- 堆上
new String(...) 新物件,複製常量池內容
- 答案:1 或 2 個(視常量池是否已有
"abc")
Q3: 字串作為參數傳遞是值傳遞還是引用傳遞?
- Java 只有值傳遞。傳遞的是引用的副本
- 方法內修改參數指向(
str = "new")不影響外部引用
- 但若傳入
StringBuilder,方法內 sb.append() 會影響外部物件(同一物件)
void change(String str) { str += "test"; } // 區域變數 str 指向新物件,原物件不變
void changeSB(StringBuilder sb) { sb.append("test"); } // 修改同一物件,外部可見
Q4: String.intern() 作用?
- 若常量池已有內容相同字串,返回池中引用
- 否則將此字串加入池並返回引用
- 用途:手動入池節省記憶體、加速
== 比較(慎用)
五、JDK 9+ 優化:Compact Strings
private final byte[] value; + byte coder; (LATIN1=0, UTF16=1)
- 純 ASCII 字串佔用記憶體減半
- 透明相容,無需程式碼變更
六、最佳實踐總結
| 場景 | 推薦 | 理由 |
| 不可變字串常量 | String | 常量池複用、線程安全、安全性 |
| 單執行緒大量拼接 | StringBuilder | 無同步開銷、O(n) 效能 |
| 多執行緒共享緩衝區 | StringBuffer | 線程安全 |
| 簡單拼接 2-3 字串 | + 操作符 | 編譯器自動優化為 StringBuilder |
需頻繁 == 比較 | intern() 謹慎使用 | 入池佔用堆記憶體,需權衡 |
| 字串參數傳遞 | 理解值傳遞引用副本 | 方法內重新指向不影響外部 |
七、總結
String 不可變是為了常量池複用、線程安全、安全性;StringBuilder 是單執行緒高效拼接首選;StringBuffer 保留給多執行緒共享場景。理解常量池、intern()、參數傳遞語義、JDK 9 Compact Strings,能讓你寫出高效、正確、記憶體友善的字串處理代碼。
- 上一篇文章: 【Java 每日一題】20170301:類初始化順序與靜態/實例變數賦值陷阱
- 下一篇文章: Java 基礎:深入理解 static 關鍵字
Copyright ©
程式碼之家 All Rights Reserved