在java中,字符串的加法是如何實現的?
當我查看String類的concat函數的源碼時,發現字符串連接是這么實現的:
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);
- }
那么,字符串的連接符(+)的實現和這個有什么區別呢?如果有區別的話,那它是如何實現的呢?
此外,這兩者分別在什么場合使用,有沒有性能上的差異。
為了回答這個問題,我們可以做一個測試。
首先,我們連接兩個字符串
Java代碼:
- String s1 = "foo";
- String s2 = "bar";
- String s3 = s1 + s2;
下面我們將這個代碼編譯成class文件,然后再反編譯(可以用JAD),我們得到反編譯后的代碼是:
Java代碼:
- String s = "foo";
- String s1 = "bar";
- String s2 = (new StringBuilder()).append(s).append(s1).toString();
所以,+ 和 concat 肯定是有區別的。
在性能上,從 concat() 源碼可以看出,StringBuilder創建了更多的對象,而concat卻沒有,它使用的String類的內部實現。
綜上,當我們需要連接兩個字符串的時候,我們應當優先考慮使用 concat() 函數,當我們需要連接字符串和其它類型的變量時,再考慮使用+運算符。
譯者注:用 javap -c 查看java生成的字節碼:
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 其實等價于
原文來自站長網www.software8.co/
原文來自站長網www.software8.co/
Java代碼:
- a = new StringBuilder()
- .append(a)
- .append(b)
- .toString();