深切哀悼
抗擊新冠肺炎疫情鬥爭犧牲烈士和逝世同胞html
本文內容主要爲轉載內容。 主要記錄關於String、StringBuilder、StringBuffer的深刻理解。
MO_or將結合JDK8源碼去理解String、StringBuilder、StringBuffer各自的優劣與使用場景。
先看下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去自動轉。
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中調用的)。
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方法。
綜上所述,String、StringBuilder、StringBuffer的使用場景以下: 當處理定長字符串時,建議用String; 當處理變長字符串時,而且是單線程環境時,建議用StringBuilder; 當處理變長字符串時,而且是多線程環境時,建議用StringBuffer。
深刻理解String, StringBuffer, StringBuilder的區別(基於JDK1.8)
MO_or關於static的感悟
嗶哩嗶哩java