String和StringBuffer和StringBuilder的區別

本章環境java 1.8

String

字符串拼接會重新生成新的字符串

String a= "123";
String a=a+"123";

代碼及反編譯結果

public class Main{
    
    public static void main(String[] args) {
        String str =  new  String("abc");
    }
}

反編譯結果



Constant pool:
   #1 = Methodref          #7.#16         // java/lang/Object."<init>":()V
   #2 = Class              #17            // Main
   #3 = Methodref          #2.#16         // Main."<init>":()V
   #4 = Class              #18            // java/lang/String
   #5 = String             #19            // abc
   #6 = Methodref          #4.#20         // java/lang/String."<init>":(Ljava/lang/String;)V
   #7 = Class              #21            // java/lang/Object
   #8 = Utf8               <init>
   #9 = Utf8               ()V
  #10 = Utf8               Code
  #11 = Utf8               LineNumberTable
  #12 = Utf8               main
  #13 = Utf8               ([Ljava/lang/String;)V
  #14 = Utf8               SourceFile
  #15 = Utf8               Main.java
  #16 = NameAndType        #8:#9          // "<init>":()V
  #17 = Utf8               Main
  #18 = Utf8               java/lang/String
  #19 = Utf8               abc
  #20 = NameAndType        #8:#22         // "<init>":(Ljava/lang/String;)V
  #21 = Utf8               java/lang/Object
  #22 = Utf8               (Ljava/lang/String;)V

當new String("abc")時,其實會先在字符串常量區生成一個abc的對象,然後new String()時會在堆中分配空間,然後此時會把字符串常量區中abc複製一個給堆中的String(這裏不是很清楚,是複製還是引用??),故abc應該在堆中和字符串常量區。

StringBuffer&StringBuilder

都是繼承AbstractStringBuilder實現

所以擴容的方式也是利用AbstractStringBuilder的擴容方式,2n+2的方式擴容

void expandCapacity(int minimumCapacity) {
        int newCapacity = value.length * 2 + 2;
        if (newCapacity - minimumCapacity < 0)
            newCapacity = minimumCapacity;
        if (newCapacity < 0) {
            if (minimumCapacity < 0) // overflow
                throw new OutOfMemoryError();
            newCapacity = Integer.MAX_VALUE;
        }
        value = Arrays.copyOf(value, newCapacity);
    }

常用方法

  • 獲得某個位置上的字符s.charAt(1)
  • 修改某個位置上的字符s.setCharAt(1,'1')
  • 後綴字符串s.append("11")

不同點

StringBuffer是線程安全,對大部分方法使用synchronized修飾,如:append方法

StringBuilder是線程不安全

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章