String、StringBuffer、StringBuilder 源碼解析

String、StringBuffer、StringBuilder 這三個(gè)類是 Java 字符串處理的核心類,本質(zhì)區(qū)別:String 不可變,StringBuffer/StringBuilder 可變,底層源碼圍繞「字符數(shù)組存儲(chǔ)」「不可變/可變?cè)O(shè)計(jì)」「線程安全」三大核心實(shí)現(xiàn)。

一、核心前置知識(shí)

  1. 底層存儲(chǔ):三者底層都是char[] 數(shù)組(JDK 9+ 優(yōu)化為 byte[] + coder,減少內(nèi)存占用,邏輯一致);
  2. 不可變 vs 可變
    • String:字符數(shù)組被 final 修飾,無法修改數(shù)組內(nèi)容和引用;
    • StringBuffer/StringBuilder:繼承自 AbstractStringBuilder,字符數(shù)組無 final 修飾,支持動(dòng)態(tài)擴(kuò)容和修改;
  3. 線程安全:StringBuffer 方法加了 synchronized 鎖,線程安全;StringBuilder 無鎖,線程不安全。

二、String 源碼解析(不可變字符串)

1. 核心成員變量

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    // 核心:被 final 修飾的 char 數(shù)組 → 字符串不可變的根本原因
    private final char value[];
    // 緩存哈希值,避免重復(fù)計(jì)算
    private int hash; 
}
  • final class:String 類不能被繼承;
  • final char value[]:數(shù)組引用不可變,數(shù)組內(nèi)容不可修改,任何字符串操作都會(huì)生成新對(duì)象。

2. 構(gòu)造方法(核心)

最常用的構(gòu)造器,直接復(fù)制字符數(shù)組,保證不可變:

public String(char value[]) {
    this.value = Arrays.copyOf(value, value.length);
}
  • 為什么用 Arrays.copyOf?防止外部修改傳入的數(shù)組,影響 String 內(nèi)部值。

3. 核心方法:拼接/修改(必生成新對(duì)象)

String 沒有任何修改原數(shù)組的方法,所有操作(substring/replace/+)都是新建 String 對(duì)象

// substring 源碼:新建字符數(shù)組 → 新建 String 對(duì)象
public String substring(int beginIndex) {
    // 邊界判斷...
    return new String(value, beginIndex, subLen);
}

關(guān)鍵結(jié)論:頻繁字符串拼接(如循環(huán)中用 +),會(huì)創(chuàng)建大量臨時(shí)對(duì)象,性能極差。

4. 不可變的優(yōu)勢

  1. 線程安全(無需同步);
  2. 常量池緩存,節(jié)約內(nèi)存;
  3. 哈希值固定,適合作為 HashMap 鍵。

三、AbstractStringBuilder 源碼解析(父類,可變核心)

StringBuffer 和 StringBuilder 都繼承此類,90% 的方法(append/insert/delete)都在這個(gè)父類中實(shí)現(xiàn),是可變字符串的核心。

1. 核心成員變量

abstract class AbstractStringBuilder implements Appendable, CharSequence {
    // 無 final 修飾 → 數(shù)組可修改、可擴(kuò)容
    char[] value;
    // 實(shí)際存儲(chǔ)的字符數(shù)量(不是數(shù)組長度)
    int count;
}
  • count:有效字符長度,value.length 是數(shù)組總?cè)萘浚A(yù)留擴(kuò)容空間)。

2. 動(dòng)態(tài)擴(kuò)容機(jī)制(核心)

所有追加操作都會(huì)先判斷容量,不足則自動(dòng)擴(kuò)容:

// 擴(kuò)容核心邏輯
private void ensureCapacityInternal(int minimumCapacity) {
    // 所需容量 > 當(dāng)前數(shù)組長度 → 擴(kuò)容
    if (minimumCapacity - value.length > 0) {
        // 新容量 = 原容量*2 + 2
        int newCapacity = value.length * 2 + 2;
        // 防止溢出,取最大值
        if (newCapacity - minimumCapacity < 0)
            newCapacity = minimumCapacity;
        // 復(fù)制數(shù)組到新容量
        value = Arrays.copyOf(value, newCapacity);
    }
}
  • 默認(rèn)初始容量:16;
  • 傳入字符串時(shí):容量 = 字符串長度 + 16。

3. 核心方法:append(可變的關(guān)鍵)

直接在原數(shù)組追加字符,不創(chuàng)建新對(duì)象

public AbstractStringBuilder append(String str) {
    if (str == null) str = "null";
    int len = str.length();
    // 擴(kuò)容判斷
    ensureCapacityInternal(count + len);
    // 直接復(fù)制到原數(shù)組,修改 count
    str.getChars(0, len, value, count);
    count += len;
    return this;
}

關(guān)鍵:返回 this,支持鏈?zhǔn)秸{(diào)用(append().append())。

四、StringBuffer 源碼解析(線程安全可變字符串)

1. 類定義

public final class StringBuffer
    extends AbstractStringBuilder
    implements java.io.Serializable, CharSequence

直接繼承 AbstractStringBuilder,復(fù)用所有可變方法。

2. 核心:線程安全實(shí)現(xiàn)

所有對(duì)外方法都加了 synchronized 同步鎖

// append 方法:加鎖
public synchronized StringBuffer append(String str) {
    toStringCache = null;
    super.append(str);
    return this;
}

// 其他方法:length()/delete()/insert() 都加鎖
public synchronized int length() {
    return count;
}

3. 特點(diǎn)

  • 線程安全,多線程環(huán)境下安全;
  • 加鎖有性能開銷,速度慢于 StringBuilder。

五、StringBuilder 源碼解析(非線程安全可變字符串)

1. 類定義

public final class StringBuilder
    extends AbstractStringBuilder
    implements java.io.Serializable, CharSequence

和 StringBuffer 完全一致,唯一區(qū)別:無同步鎖

2. 核心方法

直接復(fù)用父類方法,沒有任何 synchronized 修飾

public StringBuilder append(String str) {
    super.append(str);
    return this;
}

3. 特點(diǎn)

  • 無線程安全保障,單線程專用;
  • 無鎖開銷,速度最快,是單線程字符串拼接首選。

六、三者核心源碼對(duì)比總結(jié)

特性 String StringBuffer StringBuilder
底層存儲(chǔ) final char[](不可變) char[](可變,繼承父類) char[](可變,繼承父類)
可變性 不可變,操作生成新對(duì)象 可變,直接修改原數(shù)組 可變,直接修改原數(shù)組
線程安全 安全(不可變) 安全(synchronized 鎖) 不安全
性能 最差(頻繁拼接產(chǎn)生垃圾對(duì)象) 中等(加鎖開銷) 最快(無鎖)
使用場景 少量字符串、常量、多線程 多線程環(huán)境下頻繁拼接 單線程環(huán)境下頻繁拼接

總結(jié)

  1. String:不可變,底層 final char[],適合少量、不變的字符串;
  2. AbstractStringBuilder:父類,實(shí)現(xiàn)可變核心和動(dòng)態(tài)擴(kuò)容;
  3. StringBuffer:線程安全,加同步鎖,多線程拼接用;
  4. StringBuilder:非線程安全,無鎖,單線程拼接首選。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容