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 publicString 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 就会开始工作,对速度的影响一定是相当大的。