String、StringBuffer、StringBuilder,bufferbuilder

來源:互聯網
上載者:User

String、StringBuffer、StringBuilder,bufferbuilder

也說String。

  • String:不可變字元序列。
  • StringBuffer:安全執行緒的可變字元序列。
  • StringBuilder:StringBuffer的非安全執行緒實現,JDK1.5+。
public final class String {          private final char value[];            public String(String original) {               // 把原字串original切分成字元數組並賦給value[];          } }//StringBuffer  public final class StringBuffer extends AbstractStringBuilder  {          char value[]; //繼承了父類AbstractStringBuilder中的value[]          public StringBuffer(String str) {                  super(str.length() + 16); //繼承父類的構造器,並建立一個大小為str.length()+16的value[]數組                  append(str); //將str切分成字元序列並加入到value[]中         } }

 

1    常量池

在Java原始碼中的每一個字面值字串,都會在編譯成class檔案階段,形成標誌號為8(CONSTANT_String_info)的常量表。 當JVM載入 class檔案的時候,會為對應的常量池建立一個記憶體資料結構(StringTable,它是一個hashtable,key是字串的hashcode,value是字串的引用地址。),並存放在方法區中。同時JVM會自動為CONSTANT_String_info常量表中的字串常量字面值在堆中建立新的String對象(intern字串對象)。然後把CONSTANT_String_info常量表的入口地址轉變成這個堆中String對象的直接地址(常量池解析)。

樣本:

String sc="ab"+"cd"; String sd="abcd"; System.out.println(sc==sd); //true,在應用啟動完成時就已經載入至常量池了 

 

2    StringBuilder與String+
String sa = "a";String s = sa + "b";

javap -c查看虛擬機器指令:

       0: ldc           #2                  // String a       2: astore_1       3: new           #3                  // class java/lang/StringBuilder       6: dup       7: invokespecial #4                  // Method java/lang/StringBuilder."<init>":()V      10: aload_1      11: invokevirtual #5                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;      14: ldc           #6                  // String b      16: invokevirtual #5                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;      19: invokevirtual #7                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;      22: astore_2      23: return

 

由上可以看到,String+實際上的操作就是new StringBuilder().append().append….toString()。因此如下方法不會引起效率問題(除非連結字串較長時,因為String+操作預設初始化大小16導致append時多次resize):

String method(String sa) {     return sa + "b";}

 

一般所說的String+效率低下的主要產生在如下情況:

String method(String sa) {      for (int i=0; i<100; i++) {            sa += "b";      }      return sa;}

 

每做一次+就產生一個StringBuilder對象,然後append後丟掉。下次迴圈重新產生一個StringBuilder對象。如果我們直接使用StringBuilder對象全程append的話,就可以節省N-1次建立與銷毀對象的時間。

通過上面的說明,我們可以知道如下結果:

String sa = "ab";  String sb = "cd";  String sab = sa+sb; String s = "abcd"; System.out.println(sab==s); // false 

 

3    String.intern

String.intern可以將一個String類的儲存到一個全域StringTable表中,如果具有相同值的Unicode字串已經在這個表中,那麼該方法返回表中已有字串的地址,如果在表中沒有相同值的字串,則將自己的地址註冊到表中。

通過這個方法我們可以測試常量池到底佔用JVM的哪一地區。

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.