Java用String、StringBuilder、StringBuffer三个类来封装对字符串的操作。
- String类中对字符串的保存格式为
private final char value[];
它被final所修饰,所以它是不可变的,从它被创建直至被销毁,它的字符序列都没有改变,我们对它的一系列操作都是通过创建新的String对象来完成的。
- StringBuilder、StringBuffer两个类都继承自抽象类AbstractStringBuilder,它们对字符串的保存格式为
char[] value;
所以它们是可变的,我们可以通过它提供的方法(如append(),insert()等)通过直接修改字符序列来完成对字符串的操作。
StringBuilder、StringBuffer与String类之间的转换
当我们通过一系列对StringBuilder、StringBuffer对象的转换后得到最终自己需要的字符串,可以通过toString()方法来将StringBuilder、StringBuffer对象转化为String对象。
抽象父类AbstractStringBuilder中的toString()方法:
public abstract String toString();
那StringBuilder与StringBuffer方法有什么区别呢?
首先我们来看它们其中的一个方法,就拿setLength(int newLength)举例
- 在AbstractStringBuilder中:
public void setLength(int newLength) {
if (newLength < 0)
throw new StringIndexOutOfBoundsException(newLength);
ensureCapacityInternal(newLength);
if (count < newLength) {
Arrays.fill(value, count, newLength, '\0');
}
count = newLength;
}
- 在StringBuffer中:
public synchronized void setLength(int newLength) {
toStringCache = null;
super.setLength(newLength);
}
- StringBuilder则是直接继承了抽象类方法。
通过查看原码我们发现StringBuffer对AbstractStringBuilder的许多方法进行了重写,用synchronized修饰符为某些方法加上了同步锁,这使得StringBuffer的对象被多个线程共同调用时更加安全。
而StringBuilder则因为没有关于多线程的相关处理,使得其效率要比StringBuffer要高
那我们分别应该何时使用这三种方法?
- (可变性)当我们不对存入的字符串序列进行变化时用String,而如果经常要对存储的序列进行变化时应使用StringBuffer或StringBuilder。
- (安全性与效率)当只在单线程中使用时,选用效率更高的StringBuilder,而如果应用于多线程,应选用更安全的StringBuffer