Java面试之String、StringBuffer和StringBuilder的区别和原理
先解释一下String
String对象一旦创建其值是不能修改的,如果要修改,会重新开辟新的内存空间来存储修改后的对象,也就是修改了String的引用,String底层是通过数组来存储值得,这一特性也就导致了上述问题,进入到String中可以看到是被final修饰的,所以它也不可以被继承;
如果我们在实际开发中需要对一个值频繁的修改,使用String会导致内存空间的浪费,那该如果解决这个问题呢?下边解释一下StringBuffer和StringBuilder
StringBuffer的详解
StringBuffer存储数据的形式和String是一样的,底层都是通过数组来存储值,Stringbuffer的数组初始长度为16,也就是说实例化一个StringBuffer对象,那么它的初始大小就是16,即创建了一个大小为16的字符字符串缓冲区。
不过当我们调用一个有参构造函数创建StringBuffer的话,那么它的初始长度就不是16了,那就是“对象值的长度+16”
StringBuffer的扩容是多少呢?一般如果存储值的长度大于StringBuffer初始长度(16),扩容的逻辑是创建一个新的char数组,这个新的char数组的长度将会是现有长度的一倍再+2,如果还是不够大,直接长度等于现有的长度,扩容完成之后,会将原数组中的值复制到新数组中,char的指针指向新的数组
StringBuilder的详解
StringBuilder和StringBuffer一样,都拥有同一个父类AbstractStringBuilder
,并且都实现了java.io.Serializable, CharSequence
的接口
那它俩的区别在哪?
首先StringBuffer实现的所有接口都是线程同步的,所以线程安全,在多线程中能保证数据同步;而StringBuilder没有实现线程同步,线程不安全,所以不能在多线程中使用。
如果是多线程的情况下推荐使用StringBuffer,如果不怎么考虑线程安全的话,追求效率推荐使用StringBuilder