String 在java中是不可變的,每一個對String進行操做的方法實際上都是返回一個新的String對象,並使原來的String對象不可達。對String的鏈接常有下面幾種方法,一種是使用‘+’符號,另外一種是使用StringBuilder,再就是String的concat方法。 java
(1) ‘+’: app
爲了研究'+'的實現,咱們寫如下測試代碼: 工具
public static void main(String[] args) { String a="hell"+"o"; //code1 String b="world"; for(int i=0;i<4;i++) { a+=b; //code2 } }把上面代碼編譯後再用jdk的反編譯工具(javap)反編譯下,獲得以下代碼:
public static void main(java.lang.String[]); Code: 0: ldc #16; //String hello 2: astore_1 3: ldc #18; //String world 5: astore_2 6: iconst_0 7: istore_3 8: goto 33 11: new #20; //class java/lang/StringBuilder 14: dup 15: aload_1 16: invokestatic #22; //Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String; 19: invokespecial #28; //Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V 22: aload_2 23: invokevirtual #31; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 26: invokevirtual #35; //Method java/lang/StringBuilder.toString:()Ljava/lang/String; 29: astore_1 30: iinc 3, 1 33: iload_3 34: iconst_4 35: if_icmplt 11 38: return從code1能夠獲得「若是在‘+’左右沒有變量的時候,‘+‘的結果是直接得出的。
從code2能夠獲得,若是在‘+’左右有變量的時候,會生成一個StringBuilder對象,而後調用其append方法。 測試
在一個拼接String的語句中,若是被拼接的String中有String對象,那這個語句會生成一個StringBuilder對象,而後調用其append方法. ui
注意源碼中的循環,反編譯後在代碼中對應的是<line>8</line>到<line>35</line>,而建立StringBuilder對象被包含在了循環內,因此上面的代碼會建立過多StringBuilder對象而影響效率。 this
(2) StringBuilder lua
下面咱們來分析下StringBuilder的append方法,其源碼以下: code
public StringBuilder append(String str) { super.append(str); return this; }super.append(str)以下:
public AbstractStringBuilder append(String str) { if (str == null) str = "null"; int len = str.length(); if (len == 0) return this; int newCount = count + len; if (newCount > value.length) expandCapacity(newCount);//此方法拓展StringBuilder的容量至當前容量的2倍 str.getChars(0, len, value, count); count = newCount; return this; }經過分析源碼咱們能夠發現StringBuilder的效率是很高的(這也是java編譯器默認採用StringBuilder的緣由),但要注意拓展容量的操做,因此適當設置初始容量是頗有必要的。
(3)String的concat方法 對象
其源碼以下: ci
public String concat(String str) { int otherLen = str.length(); if (otherLen == 0) { return this; } char buf[] = new char[count + otherLen]; getChars(0, count, buf, 0); str.getChars(0, otherLen, buf, count); return new String(0, count + otherLen, buf); }
這個方法的做用很簡單,就是建立一個新String對象。
結論:
定義三個變量:String a="a",b="b",c="c";
1.對於簡單拼接,如String d=a+b,建議使用concat方法:String d=a.concat(b);來減小生成沒必要要的StringBuilder對象
2.對於二次以上拼接,如String d=a+b+c,使用這種方式就能夠
3.對於涉及到循環的拼接,如:
String d=""; String e=""; for(int i=0;i<10;i++) { d+=a;//或d=d+a; e+=(a+b);//或e=e+a+b; }
建議採用如下方式:
StringBuilder d = new StringBuilder(10)//設置初始容量以減小拓容操做 StringBuilder e = new StringBuilder(20); for(int i=0;i<10;i++) { d.append(a); e.append(a).append(b); }#本文參考自《thinking in java》第四版Strings章節