String,StringBuffer, StringBuilder 的区别到底是什么

这个问题,在现在的面试中,笔试中经常遇到,这个问题可能很多人都能回答,String是不可变的,StringBuffer和StringBuilder是可变的,在有大量的字符串操作时使用StringBuffer或者StringBuilder,StringBuffer相对于StringBuilder是线程安全的。这样的回答是没有错的。很多java面试宝典上的答案都是这么一句答案,这么答也没错。至于缺少点什么我也不知道,但是总觉得缺少点什么。以前去参加面试时面试官也问过我这么一个问题,不过别人好像对我说的答案不太满意。好吧,估计是没有说到重点吧,扯远了。

我们都知道String是一个final类,至于StringBuffer和StringBuilder类呢,其实他们也是一个final类

String.class

[java] view plaincopy

  1. public final class String implements java.io.Serializable, Comparable<String>, CharSequence  

StringBuffer.class

[java] view plaincopy在CODE上查看代码片派生到我的代码片

  1. public final class StringBuffer extends AbstractStringBuilder implements java.io.Serializable, CharSequence  

其实这三个类里的真正值是一个char[]数组,String里面的char[]数组是final类型,一旦被指定了,就不能更改了,且String还没有对char[]操作的方法

但是另外两个类的char[]数组没有被定义为final,虽然他们本身是final类,他们定义的变量不能指向其它对象,但是他们本身char[]是可以改变的。并且他们自身也提供了对char[]的操作。

char[]长度不够时,调用了Arrays.copyOf(value, newCapacity);最终还是调用了System.arraycopy

如果用String来进行字符串的连接,那么会创建出很多的对象。特别是在大循环里对字符串直接使用+来进行连接,如果使用StringBuffer或者StringBuffer来进行字符串的拼接,使用append方法,对其操作即直接操作对象指向的引用,没有建立过多的对象,底层都是对char[]的操作

以上都是在不涉及到反射。

标签