美文网首页
java 类中contact方法和 + 连接字符串的区别

java 类中contact方法和 + 连接字符串的区别

作者: 十维_fun | 来源:发表于2018-07-29 15:45 被阅读0次

    基本概念

    1、concat()方法是String类的一个方法

            要有一个String类对象调用,而且需要传递一个String类对象作为参数。结果返回的是两个String类对象拼接成的对象。

    2、+是String类重载的一个操作符

    在处理String对象时,需要创建一个StringBuffer对象,然后用这个对象的append()方法进行拼接,最后将拼接成的对象调用toString()方法,返回一个字符串对象。

    3、详细对比

     1)   concat源

    publicStringconcat(String str){intotherLen = str.length();if(otherLen ==0) {returnthis;    }charbuf[] =newchar[count + otherLen];    getChars(0, count, buf,0);    str.getChars(0, otherLen, buf, count);returnnewString(0, count + otherLen, buf);}

    2)源码中对String中+操作符的描述如下

    The Java language provides special support for the string concatenation operator ( + ), and for conversion of  other objects to strings. String concatenation is implemented  through the StringBuilder(or StringBuffer) class and its append method.

    简单的概括下:String本身是不变的对象,但是string的+号操作符是通过StringBuilder或StringBuffer(可以通过反汇编class文件,看到使用的StringBuilder来实现的。)

    细节:+ 的效率一定高于contact方法吗?

        String通过“+”拼接的时候,如果拼接的对象是常量,则会在被编译器编译时优化,合并操作在编译阶段就完成,不需要运行时再去分配一个空间,自然效率是最高的。

    // 原始代码String a ="a";String b ="b";String c = a + b +"f";// 编译器会将它编译为:(实际场景中这是class字节码的内容,temp是虚拟出来的)String a ="a";String b ="b";StringBuilder temp =newStringBuilder;temp.append(a).append(b).append("f");String c = temp.toString();

     在循环过程中,a引用所指向的字符串会越来越大,这就意味着垃圾空间也会越来越大,a所指字符串达到一定程度后必然会进入Old区域。若占用的空间达到Old的1/4,就有可能发生OOM。

     StringBuilder.append()的源码如下:

    publicStringBuilderappend(String str){super.append(str);returnthis;}publicAbstractStringBuilderappend(String str){if(str ==null)str ="null";intlen = str.length();if(len ==0)returnthis;intnewCount = count + len;if(newCount > value.length)expandCapacity(newCount);str.getChars(0, len, value, count);count = newCount;returnthis;}voidexpandCapacity(intminimumCapacity){intnewCapacity = (value.length +1) *2;if(newCapacity <0){newCapacity = Integer.MAX_VALUE;}elseif{minimumCapacity > newCapacity) {newCapacity = minimumCapacity;}value = Arrays.copyOf(value, newCapacity);}

        假如append()的随机字符串是空字符串“ ”,就不会发生扩容,最后需要toString() 方式来创建一个新的对象,这个过程会开辟一个同样大小的空间将内容拷贝进去。

      另外,在StringBuilder.append()中间过程中产生的垃圾内存大多数都是小块的内存,它所产生的垃圾就是拼接的对象以及扩容时原来的空间。在这种场景下,通常使用StringBuilder来拼接字符串效率会高出许多倍。

        所以,明确一点,不是String的“”+”操作本身慢,而是大量循环中大量的内存使用使得它的内存开销变大,导致了频繁GC,而且是更多的FULL GC,效率才会急剧下降。

    总结:

        1、两种方法在内存使用上,都是要先创建一段空间,然后销毁。区别就是使用形式上,一个是方法,另一个是重载了一个运算符。

        2、在实际操作中当在大量操作string字符串时,StringBuilder的append方法是最好的选择,少量则是append的效率会更高。

    参考书籍:《Java特种兵》

    论坛:黑马程序员论坛

    相关文章

      网友评论

          本文标题:java 类中contact方法和 + 连接字符串的区别

          本文链接:https://www.haomeiwen.com/subject/btazmftx.html