在java中,字符串的加法是如何實(shí)現(xiàn)的?
當(dāng)我查看String類的concat函數(shù)的源碼時(shí),發(fā)現(xiàn)字符串連接是這么實(shí)現(xiàn)的:
Java代碼:
- public String concat(String str) {
- int otherLen = str.length();
- if (otherLen == 0) {
- return this;
- }
- int len = value.length;
- char buf[] = Arrays.copyOf(value, len + otherLen);
- str.getChars(buf, len);
- return new String(buf, true);
- }
那么,字符串的連接符(+)的實(shí)現(xiàn)和這個(gè)有什么區(qū)別呢?如果有區(qū)別的話,那它是如何實(shí)現(xiàn)的呢?
此外,這兩者分別在什么場(chǎng)合使用,有沒有性能上的差異。
為了回答這個(gè)問題,我們可以做一個(gè)測(cè)試。
首先,我們連接兩個(gè)字符串
Java代碼:
- String s1 = "foo";
- String s2 = "bar";
- String s3 = s1 + s2;
下面我們將這個(gè)代碼編譯成class文件,然后再反編譯(可以用JAD),我們得到反編譯后的代碼是:
Java代碼:
- String s = "foo";
- String s1 = "bar";
- String s2 = (new StringBuilder()).append(s).append(s1).toString();
所以,+ 和 concat 肯定是有區(qū)別的。
在性能上,從 concat() 源碼可以看出,StringBuilder創(chuàng)建了更多的對(duì)象,而concat卻沒有,它使用的String類的內(nèi)部實(shí)現(xiàn)。
綜上,當(dāng)我們需要連接兩個(gè)字符串的時(shí)候,我們應(yīng)當(dāng)優(yōu)先考慮使用 concat() 函數(shù),當(dāng)我們需要連接字符串和其它類型的變量時(shí),再考慮使用+運(yùn)算符。
譯者注:用 javap -c 查看java生成的字節(jié)碼:
Java代碼:
- java.lang.String cat(java.lang.String, java.lang.String);
- Code:
- 0: new #2; //class java/lang/StringBuilder
- 3: dup
- 4: invokespecial #3; //Method java/lang/StringBuilder."<init>":()V
- 7: aload_1
- 8: invokevirtual #4; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
- 11: aload_2
- 12: invokevirtual #4; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
- 15: invokevirtual #5; //Method java/lang/StringBuilder.toString:()Ljava/lang/ String;
- 18: astore_1
- 19: aload_1
- 20: areturn
可以看出 a += b 其實(shí)等價(jià)于
原文來自站長(zhǎng)網(wǎng)www.software8.co/
原文來自站長(zhǎng)網(wǎng)www.software8.co/
Java代碼:
- a = new StringBuilder()
- .append(a)
- .append(b)
- .toString();
posted on 2012-12-31 13:39 你爸是李剛 閱讀(1512) 評(píng)論(0) 編輯 收藏