[Java]String中“+”的實現原理及效率
在Java中String的操作很多時候都與連接符"+"有關,比如我們可以用String = int + "" 將一個int整數或是其他基本類型轉為String類型,也可以用String = String + String 連接兩個字符串。那么這些連接符具體是如何實現的呢?他們的效率又如何呢?
首先我們可以在API文檔上查閱到:
Java 語言提供對字符串串聯符號("+")以及將其他對象轉換為字符串的特殊支持。字符串串聯是通過 StringBuilder(或 StringBuffer)類及其 append 方法實現的。字符串轉換是通過 toString 方法實現的,該方法由 Object 類定義,并可被 Java 中的所有類繼承。有關字符串串聯和轉換的更多信息,請參閱 Gosling、Joy 和 Steele 合著的 The Java Language Specification。
到底是否如上所說呢?決定用反編譯驗證一下,代碼如下:
public class Test {
public static void main(String[] args) {
int i = 10;
String s = "abc";
System.out.println(s + i);
}
}
反編譯后代碼變為:
public class Test {
public static void main(String args[]) { //刪除了默認構造函數和字節碼
byte byte0 = 10;
String s = "abc";
System.out.println((new StringBuilder()).append(s).append(byte0).toString());
}
}
這樣我們就能很清晰的看到,原來Java中"+"連接字符串對象時,會創建一個StringBuilder()對象并調用append()方法將數據拼接,最后調用toString()方法返回拼接好的字符串,由于append()方法的各種重載形式會調用String.valueOf方法,所以我們可以認為:
//以下兩者是等價的
s = i + ""
s = String.valueOf(i);
//以下兩者也是等價的
s = "abc" + i;
s = new StringBuilder("abc").append(i).toString();
這種JVM隱式創建StringBuilder的方式在大部分情況下并不會造成效率的損失,不過在進行大量循環拼接字符串時則需要注意,例如源代碼為:
</pre><pre name="code" class="java">public class Test {
public static void main(String[] args) {
String s = "abc";
for (int i=0; i<10000; i++) {
s += "abc";
}
}
}
反編譯后代碼為:
public class Test {
public static void main(String args[]) {
String s = "abc";
for(int i = 0; i < 1000; i++) {
s = (new StringBuilder()).append(s).append("abc").toString();
}
}
}
這樣由于大量StringBuilder創建在堆內存中,肯定會造成效率的損失,所以在這種情況下建議在循環體外創建一個StringBuilder對象調用append()方法手動拼接(如上面例子如果使用手動拼接運行時間將縮小到1/200左右)。與此之外還有一種特殊情況,也就是當"+"兩端均為字符串常量(此時指的是"abc"等而不是final修飾的String對象)時,在編譯過后會直接拼接好,例如:
public class Test {
public static void main(String[] args) {
System.out.println("Hello" + "World");
}
}
反編譯后變為:
public class Test {
public static void main(String args[]) {
System.out.println("HelloWorld");
}
}
這樣的情況效率肯定是最佳的,不過一般不會有人會用"+"拼接兩個字符串常量吧。
最后結論:在大部分情況下,使用"+"連接字符串并不會造成效率上的損失,同時可以提高程序的易讀性和簡潔度,不會擔心盡管使用便是!
————————————————
版權聲明:本文為CSDN博主「ScienJus」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/sinat_19425927/article/details/38663461

浙公網安備 33010602011771號