java里已经有了StringBuilder,为什么还要StringBuffer?今天我们就来说说StringBuffer的作用。
StringBuffer和StringBuilder都可以高效的处理字符串,StringBuffer是线程安全的,StringBuilder是线程不安全的,当然StringBuilder性能更高一些。
因此理论上在多线程的场景下我们应该使用线程安全的StringBuffer。但是在实际开发中,几乎没有场景会用到线程安全的字符串拼接器。
同时,StringBuffer的线程安全仅仅是保证jvm不抛出异常从而可以顺利的往下执行而已,并不能保证逻辑正确和调用顺序正确。
对于实际开发中,我们大多数时候需要的是锁,而不仅仅是线程安,最后,为什么会有stringbuffer的存在?答案很简单,因为最早是没有stringbuilder的,sun公司的开发者不知道处于什么考虑,决定让stringbuffer是线程安全的,然后大约10年之后,人们终于意识到这是一个愚蠢的决定,于是,在jdk1.5的时候,决定提供一个非线程安全的stringbuffer实现,并命名为stringbuilder。
如果没有循环的情况下,单行用加号拼接字符串是没有性能损失的,java编译器会隐式的替换成stringbuilder,但在有循环的情况下,编译器没法做到足够智能的替换,仍然会有不必要的性能损耗,因此,用循环拼接字符串的时候,还是老老实实的用stringbuilder吧。
要弄清楚Java之中的Buffer的作用,首先需要明白java之中Wrapper类型都是不可变的。什么是不可变类型呢?顾名思义,就是这种类型的对象一旦创建好之后,无论调用何种方法都无法改变该对象的任何的属性。你看看String类的源代码就会发现,它的所有的属性都是private final的,因此只有在构造String对象的时候,这些属性才是可以修改的。 String类的方法中需要返回一个String的,如substring,concat等,都会先构造一个新的String对象,然后返回,而原来的String对象是不会发生变化的。
这样,如果需要用大量的小字符串拼接成一个长的字符串的时候,就会构造大量的中间的字符串。如下面的例子:
String [] arr1 = new String[10]; for (int i=0; i<arr1.length; i++) arr1[i] = "Value" + i; String result = ""; for(String s : arr1) { result = result + s; }
最后一个循环执行的时候,就会生成大量的字符串临时对象:
Value0 Value0Value1 Value0Value1Value2 Value0Value1Value2Value3 … Value0Value1Value2Value3Value4Value5Value6Value7Value8Value9
这10个String对象之中,我们需要的只是最后的一个,前面的9个都会浪费内存。如果情况更糟的话,有几百个上千个,或者中间的字符串更长,浪费将会更加的严重。 StringBuffer就是为了解决这个问题。它是可变的,当修改或者追加字符串到原来的对象上是,不会新生成一个字符串,而是在原来的对象上进行修改。这样,就不用分配大量的空间给中间的临时对象了。 其他的Buffer也是类似的原理。
通过以上内容我们知道了java中stringbuffer的作用。感谢您访问“我爱捣鼓(www.woaidaogu.com)”网站的内容,希望对大家有所帮助!引用本文内容时,请注明出处!谢谢合作!