String、StringBuilder、StringBuffer的区别老生常谈,最权威的莫过于源码。基于JDK1.8。
支持原创,转载请注明出处。
继承关系
public final class StringBuilder
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence
public final class StringBuffer
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence
abstract class AbstractStringBuilder implements Appendable, CharSequence
StringBuilder、StringBuffer都继承自AbstractStringBuilder,因为这两个类的行为很像,将公共的行为提取到AbstractStringBuilder不失为一个好的选择。
核心成员变量
这两个类都将实现交给了父类AbstractStringBuilder,所以我们看下AbstractStringBuilder的成员变量:
char[] value;
int count;
很简单,就一个字符数组和成员计数。
核心方法
StringBuilder的append方法:
@Override
public StringBuilder append(String str) {
super.append(str);
return this;
}
StringBuffer的append方法:
@Override
public synchronized StringBuffer append(String str) {
toStringCache = null;
super.append(str);
return this;
}
它们的区别在于StringBuffer的append方法是synchronized修饰,所以是线程安全的。我们看下AbstractStringBuilder的append方法:
public AbstractStringBuilder append(String str) {
if (str == null)
return appendNull();
int len = str.length();
ensureCapacityInternal(count + len);//确保不会溢出,必要是扩容
str.getChars(0, len, value, count);//将整个str拷贝到value的末尾
count += len; //增加计数
return this;
}
private void ensureCapacityInternal(int minimumCapacity) {
// overflow-conscious code
if (minimumCapacity - value.length > 0) //如果会溢出,则扩容
expandCapacity(minimumCapacity);
}
void expandCapacity(int minimumCapacity) {
int newCapacity = value.length * 2 + 2; //新的容量是原容量的2倍+2
if (newCapacity - minimumCapacity < 0)
newCapacity = minimumCapacity;
if (newCapacity < 0) {
if (minimumCapacity < 0) // overflow
throw new OutOfMemoryError();
newCapacity = Integer.MAX_VALUE;
}
value = Arrays.copyOf(value, newCapacity);
}
AbstractStringBuilder的append方法和ArrayList的add方法很像,先确保不会溢出,必要时进行扩容,然后将参数str复制到value的尾部。其他方法都类似,必要时翻看源码就可以啦。
总结
StringBuilder、StringBuffer的公共操作都在AbstractStringBuilder中,StringBuilder、StringBuffer的区别在于StringBuffer的方法被synchronized修饰,保证线程安全性的同时也损失了性能。
支持原创,转载请注明出处。
github:https://github.com/gatsbydhn