在Java中,任何字符串的都是String的对象,而且不可变更,在前面的文章里,我们对这点已经分析的很透彻了,String主要存在的是问题在于它不可变以及很容易就造成的效率低下和空间浪费。所以为了弥补String的缺点,又提出了StringBuffer和StringBuilder两个类。
// Stirng类
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence
// StringBuffer类
public final class StringBuffer
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence
// StringBuilder类
public final class StringBuilder
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence
在类的继承关系上,可以看到StringBuufer和StringBuilder只是比String多继承了一个抽象类而已,在后面会讲。
1. 可变性
String对象不可变的本质是因为String用来存储字符串的字符串数组定义如下:
private final byte[] value;
实现字符串的字符数组是final修饰的,所以String一经创建,就不能改变了,而StringBuffer和StringBuilder都继承了abstractStringBuilder抽象类,它俩的字符串数据数组是同一种:
byte[] value
value没有被final修饰,这就是StringBuffer和StringBuilder可变的原因。
2. 线程安全
String的对象内容不可变,显然是线程安全的。
StringBuffer为线程安全,因为它的方法都是synchronized修饰的同步方法,而StringBuilder的方法没有用synchronized修饰,线程不安全。
虽然StringBuffer的方法为线程安全的同步方法,但是,线程安全的同时,效率肯定没有不加同步锁的StringBuilder高。
总体来说,StringBuilder效率 > StringBuffer效率 > String效率。因为String每次进行操作,都要重新创建对象实例,所以,它的效率必然是最低的。
3. StirngBuffer与StringBuilder的相同点
StringBuilder与StringBuffer有都继承了AbstractStringBuilder抽象类。该抽象类中提供了一些公共的方法一共子类使用,如果打开StringBuffer或StringBuilder的源码,可以看到很多地方使用super调用父类方法。