首先我们说一下java中String、StringBuffer和StringBuilder的相同点:
通过源码我们可以发现无论是String,StringBuffer还是StringBuilder它们的底层都是使用char[]数组进行存储。
接着我们说一下它们三者之间的不同点:
String:不可变的字符序列。
StringBuffer:可变的字符序列,是线程安全的,效率低。
StringBuilder:可变的字符序列,是线程不安全的,效率高。
现在我们通过源码分析它们的不同点:
1.分析String的源码
/** The value is used for character storage. */ private final char value[]; //char[]数组被final修饰,所以它是不可变的字符序列。
2.分析StringBuffer的源码
char[] value; //在StringBuffer的父类中,没有用final修饰,是一个可变char[]数组 public StringBuffer() { super(16); //调用父类的构造器方法 } //父类的构造器 AbstractStringBuilder(int capacity) { value = new char[capacity]; //默认为我们创建了一个长度为16的char[]数组 } //截取StringBuffer类中的一部分代码,我们可以发现方法前都是用synchronized关键字修饰的,所以是线程安全的,执行效率比较慢。 @Override public synchronized void setCharAt(int index, char ch) { if ((index < 0) || (index >= count)) throw new StringIndexOutOfBoundsException(index); toStringCache = null; value[index] = ch; } @Override public synchronized StringBuffer append(Object obj) { toStringCache = null; super.append(String.valueOf(obj)); return this; } @Override public synchronized StringBuffer append(String str) { toStringCache = null; super.append(str); return this; }
3.分析StringBuilder的源码
char[] value; //在StringBuilder的父类中,没有用final修饰,是一个可变的char[]数组 public StringBuilder() { super(16); //调用父类的构造方法 } //父类的构造器 AbstractStringBuilder(int capacity) { value = new char[capacity]; //默认为我们创建了一个长度为16的char[]数组 } //截取StringBuilder类中的一部分代码,我们可以发现方法前没有用synchronized关键字修饰,所以是线程不安全的,执行效率比较快。 public void setCharAt(int index, char ch) { if ((index < 0) || (index >= count)) throw new StringIndexOutOfBoundsException(index); value[index] = ch; } public AbstractStringBuilder append(Object obj) { return append(String.valueOf(obj)); }
注意:你在使用StringBuffer或者StringBuider时,如果字符串长度过大,建议使用它们的另外一个构造器,提前创建一个长度大的char[]数组,这样可以提高效率。
通过源码分析:
public StringBuffer(int capacity) { super(capacity); //调用父类的构造器 } //父类的构造方法 AbstractStringBuilder(int capacity) { value = new char[capacity]; //根据传入的参数,创建char[]数组的长度,这样做可以提高效率。 } public StringBuilder(int capacity) { super(capacity); //调用父类的构造器 } //父类的构造方法 AbstractStringBuilder(int capacity) { value = new char[capacity]; //根据传入的参数,创建char[]数组的长度,这样做可以提高效率。 }