line1: "abc"+"def"+"ghi"
line2: new String("abc").concat("def").concat("ghi");
line3: new StringBuffer("abc").append("def").append("ghi");
上述三行代碼的區別,尤其是在內存中的變換狀態的區別?
首先我們先看幾個概念:
1:在java內部是對+進行了重載,在處理String的過程中要創建一個StringBuffer對象,用StringBuffer對象的append方法對字符串進行連接,最后調用toString方法返回String字符串。
2: +和concat操作,是先開辟一個要拼接的字符串的空間,在和老字符串一起拼接成一個新的字符串,所以在堆內存中是創建了三塊空間的;
然后先來說1和2的區別:line1: 用的是+,+在底層是通過StringBuffer對象的append方法對字符串進行連接,但是他也並不是直接添加的,我們看看他開辟了幾塊空間?“abc”“def”“ghi”,剛開始開辟了三塊堆內存空間,執行一次+,“abcdef”這是第四塊內存空間,最后是最終結果“abcdefghi”開辟了第五塊堆內存空間,然后其余的被回收。
line2:同樣也是開辟了五塊堆內存空間,concat()和+號的區別我們可以看下concat()源代碼:
1 public String concat(String str) { 2 int otherLen = str.length(); 3 if (otherLen == 0) { 4 return this; 5 } 6 int len = value.length; 7 /*copyOf數組復制,copyOf()的第二個自變量指定要建立的新數組長度, 8 如果新數組的長度超過原數組的長度,則保留為默認值null或0*/ 9 char buf[] = Arrays.copyOf(value, len + otherLen); 10 //將字符從此字符串復制到目標字符數組,len為數組中的起始偏移量 11 str.getChars(buf, len); 12 return new String(buf, true); 13 }
我們可以看到concat()方法是通過copyOf(),和getChars();兩個方法來拼接數組的。+在底層是通過StringBuffer對象的append方法對字符串進行連接。
最后是StringBuffer:StringBuffer使用時,只會開辟一塊內存空間,使用append添加或delete刪除其內容時,也是在這一塊內存空間中並不會生成多余的空間。所以速度是比較快的而String 每次生成對象都會對系統性能產生影響,特別當內存中無引用對象多了以后, JVM 的 GC 就會開始工作,對速度的影響一定是相當大的。
