首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 核心:深度解析 String、StringBuffer 與 StringBuilder 的關鍵差異

     編輯:Java 相關知識

在 Java 開發與面試中,String、StringBuffer 與 StringBuilder 是繞不開的經典話題。三者雖同為字串處理類別,但在可變性、執行緒安全與效能表現上卻有本質區別。掌握這些差異,不僅能寫出更高效的程式碼,更能在技術面試中遊刃有餘。

一、核心差異:不可變 vs 可變

String:不可變的字串常量

String 內部使用 final char[] value 儲存字元。final 修飾符意味著陣列參考不可變,且 String 類別本身也被 final 修飾,無法被繼承。每次看似「修改」字串的操作(如拼接、替換),實際上都會在堆記憶體中建立全新的 String 物件,原物件若無引用則等待 GC 回收。

// 看似修改,實則新建物件
String s = "Hello";
s += " World"; // 產生新物件 "Hello World",原 "Hello" 失去引用

StringBuffer & StringBuilder:可變的字串建構器

兩者皆繼承自 AbstractStringBuilder,內部維護 char[] value 陣列(無 final 修飾)。擴容、新增、插入、刪除等操作直接在原陣列或擴容後的新陣列上進行,避免頻繁建立物件,大幅提升效能。

二、執行緒安全:同步鎖的取捨

類別執行緒安全實現機制適用場景
String✅ 安全不可變物件天生安全常量、少量拼接、多執行緒共享
StringBuffer✅ 安全關鍵方法加 synchronized多執行緒環境下頻繁修改字串
StringBuilder❌ 不安全無同步鎖,單執行緒最高效單執行緒、大量字串操作、效能敏感場景

StringBuffer 的核心方法(如 append()、insert()、reverse())均標註 synchronized,確保同一時間僅一個執行緒能操作內部陣列。但這也帶來鎖開銷。StringBuilder (JDK 1.5+) 移除同步鎖,在單執行緒下效能顯著優於 StringBuffer。

三、共同祖先:AbstractStringBuilder

AbstractStringBuilder 定義了 expandCapacity()、append()、insert()、indexOf() 等核心邏輯。StringBuilder 與 StringBuffer 均透過 super.append(...) 復用父類實現,差別在於 StringBuffer 在公開方法上加 synchronized。

四、效能實測與選型建議

// 單執行緒大量拼接:StringBuilder 最快
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 100000; i++) sb.append(i);

// 多執行緒共享緩衝區:必須用 StringBuffer
StringBuffer sbf = new StringBuffer();
// 執行緒 A: sbf.append("A");
// 執行緒 B: sbf.append("B");

// 少量、固定字串:直接用 String 或 "+" (編譯器優化為 StringBuilder)
String msg = "User: " + name + ", ID: " + id;
  • 單執行緒 / 區域變數 / 高頻拼接 → StringBuilder(首選)
  • 多執行緒共享 / 線程安全要求 → StringBuffer
  • 常量、鍵值、少量拼接 → String

五、常見誤區

  1. 誤以為 String s = "a" + "b" 會建立中間物件:編譯期常量折疊會直接優化為 "ab"。
  2. 以為 StringBuilder 絕對比 StringBuffer 快:單執行緒確實快,但多執行緒下若手動加鎖,反而比內建同步的 StringBuffer 更易出錯且效能無優勢。
  3. 忽略初始容量:大量拼接時指定 new StringBuilder(1024) 可減少擴容開銷。

總結:理解底層 char[] 機制、final 語義與 synchronized 代價,才能在實戰中做出最優選擇。下次面試或 Code Review 時,不妨從「為何 String 設計為不可變?」切入,展現深度思考。

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