MO_or關於String的感悟

深切哀悼
抗擊新冠肺炎疫情鬥爭犧牲烈士和逝世同胞html

1、引言

本文內容主要爲轉載內容。
主要記錄關於String、StringBuilder、StringBuffer的深刻理解。

2、總結

MO_or將結合JDK8源碼去理解String、StringBuilder、StringBuffer各自的優劣與使用場景。

2.1 String

先看下String的部分源碼。
public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    private final char value[];
    private int hash; // Default to 0

     public String() {
        this.value = new char[0];
    }

    public String(String original) {
        this.value = original.value;
        this.hash = original.hash;
    }

    public String(char value[]) {
        this.value = Arrays.copyOf(value, value.length);
    }    
    
    ...
}
String類使用了final關鍵字,表示此類是不支持繼承的,而且value也是不能修改的。再執行如下代碼。
public static void main(String[] args) {

    String string1 = new String("1");
    String string3 = "1";
    String string4 = "1";

    System.out.println(string1 == string3);
    System.out.println(string1.equals(string3));
    System.out.println(string3 == string4);
    System.out.println(string3.equals(string4));

}
輸出:
false
true
true
true
回憶MO_or關於Static的感悟中的內存圖。當String直接經過使用字符串實例化時,多個實例化都指向的常量池中同一個對象。
但缺點是頻繁的字符串拼接操做,會形成內存空間的浪費。
須要注意的是這種字符串的拼接操做,從JDK8 開始,會自動被編譯成StringBuilder,但任然不建議讓JDK去自動轉。

2.2 StringBuilder

StringBuilder的部分源碼。
public final class StringBuilder
    extends AbstractStringBuilder
    implements java.io.Serializable, CharSequence
{
        public StringBuilder() {
        super(16);
    }

        public StringBuilder(String str) {
        super(str.length() + 16);
        append(str);
    }

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

abstract class AbstractStringBuilder implements Appendable, CharSequence {
        char[] value;
        int count;
        AbstractStringBuilder(int capacity) {
        value = new char[capacity];
    }


        public AbstractStringBuilder append(String str) {
        if (str == null)
            return appendNull();
        int len = str.length();
        ensureCapacityInternal(count + len);
        str.getChars(0, len, value, count);
        count += len;
        return this;
    }

    ...
}
能夠看到StringBuilder的value是個char數組,(固然從JDK9開始,value從char數組變成了byte數組)。每次append時都是經過調用native的System.arraycopy實現的(在getChars中調用的)。

2.3 StringBuffer

StringBuffer的部分源碼。
public final class StringBuffer
    extends AbstractStringBuilder
    implements java.io.Serializable, CharSequence
{
    private transient char[] toStringCache;
    public StringBuffer() {
        super(16);
    }
    public StringBuffer(String str) {
        super(str.length() + 16);
        append(str);
    }
    public synchronized StringBuffer append(String str) {
        toStringCache = null;
        super.append(str);
        return this;
    }
    ...
}
和StringBuilder同樣,都是用了char數組保存value,append也是調用了AbstractStringBuilder的append方法。區別只是在於char數組加了transient關鍵字,以及方法上加了synchronized方法。

2.4 使用場景

綜上所述,String、StringBuilder、StringBuffer的使用場景以下:
當處理定長字符串時,建議用String;
當處理變長字符串時,而且是單線程環境時,建議用StringBuilder;
當處理變長字符串時,而且是多線程環境時,建議用StringBuffer。

3、參考

深刻理解String, StringBuffer, StringBuilder的區別(基於JDK1.8)
MO_or關於static的感悟
嗶哩嗶哩java

相關文章
相關標籤/搜索