目錄
- 一. String:不可變的字符串
- 二.StringBuilder:可變字符串
- 三.StringBuffer:線程安全的可變字符串
- 四.總結
在 Java 開發中,字符串處理是日常編碼中最頻繁的操作之一。String、StringBuilder 和 StringBuffer 這三個類雖然都用于操作字符串,但在性能、線程安全性和使用場景上存在顯著差異。
一. String:不可變的字符串
String 類是 Java 中最基礎的字符串類,其底層實現具有不可變性:
存儲結構:在 JDK 8 及之前,String 內部通過 private final char value[] 數組存儲字符;JDK 9 及以上改為 byte[] 數組(根據編碼自動選擇存儲方式,節省內存)。
不可變性:value 數組被 final 修飾,意味著一旦 String 對象創建,其內部的字符序列就無法被修改。任何看似 “修改” 的操作(如拼接、截取)都會創建新的 String 對象,原對象保持不變。
String str = "hello";
str += " world"; // 實際創建了新的 String 對象,原 "hello" 仍存在于內存中
這種設計的優勢是:
天然線程安全(多線程只能讀取,無法修改) 可作為 HashMap 等集合的鍵(哈希值不會變化) 字符串常量池復用,節省內存
但缺點也很明顯:頻繁修改會產生大量臨時對象,導致 GC 壓力增大,性能下降。
二.StringBuilder:可變字符串
存儲結構:內部通過 char[] value 數組存儲(無 final 修飾),支持動態擴容。
默認初始容量為 16; 當字符長度超過當前容量時,會創建一個新的數組(容量為原容量的 2 倍 + 2),并將原數據復制到新數組中。
可變性:所有修改操作(如 append()、insert()、delete())都直接操作底層數組,不會創建新對象(除非需要擴容)。
StringBuilder sb = new StringBuilder("hello");
sb.append(" world"); // 直接在原數組上修改,不創建新對象
由于省去了創建新對象的開銷,且沒有同步鎖的消耗,StringBuilder 成為單線程下字符串拼接的首選。
三.StringBuffer:線程安全的可變字符串
tringBuffer 是早期 Java 提供的可變字符串類,與 StringBuilder 最大的區別是線程安全性:
存儲結構:與 StringBuilder 基本一致,內部也是 char[] value 數組。
線程安全:通過在所有公共方法上添加 synchronized 關鍵字實現線程安全,確保多線程環境下的操作原子性。
public synchronized StringBuffer append(String str) {// 具體實現
}
這種設計保證了線程安全,但也帶來了同步鎖的性能開銷,因此在單線程環境下效率低于StringBuilder。