String, StringBuffer与StringBuilder的区别
先看一下整体的继承结构:
可知, StringBuilder与 StringBuffer都继承自 AbstractStringBuilder。
1. 可变与不可变
从源码中,我们可以看到String类中是使用字符数组来保存字符串的。
private final char value[];
此字符数组用final来修饰。,所以知道String对象是不可变的。
StringBuffer与StringBuilder是继承 AbstractStringBuilder 类,在 AbstractStringBuilder 类中也是使用字符数组来保存字符串的。
char[] value;
从此源码中可知这两种对象是可变的。
2. 是否线程安全
学习一个类,看源码,分析源码无疑是最好的一种方式。
String中的对象是不可变的,也就可以理解为常量,显然线程安全。
StringBuilder类中没有对方法加锁,是线程不安全的。
而我们随意找一下StringBuffer中的方法:
@Override
public synchronized String substring(int start, int end) {
return super.substring(start, end);
}
/**
* @throws StringIndexOutOfBoundsException {@inheritDoc}
* @since 1.2
*/
@Override
public synchronized StringBuffer insert(int index, char[] str, int offset,
int len)
{
toStringCache = null;
super.insert(index, str, offset, len);
return this;
}
可以看到StringBuffer对方法加了同步锁或者对调用的方法加了同步锁,保证了线程安全。
最后,如果不是多线程下,使用StringBuilder的效率高于StringBuffer。
使用场景:
String:适用于少量的字符串操作的情况。
StringBuilder:适用于单线程下在字符缓冲区进行大量操作的情况。
StringBuffer:适用多线程下在字符缓冲区进行大量操作的情况。