在 Java String类源码阅读笔记 里学习了String类的源码,StringBuilder、StringBuffer是经常拿来和String类做对比的两个类,可谓是“爱恨纠缠” ,这里我们继续学习这两个类的源码。
本文基于jdk1.8。
StringBuilder/StringBuffer继承关系
StringBuilder、StringBuilder具有相同的继承关系,都继承自AbstractStringBuilder类,实现了CharSequence接
口。
AbstractStringBuilder
这里我们先看一下AbstractStringBuilder这个类,StringBuilder、StringBuffer中的很多方法都是调用它们的父类。
属性
//用作字符存储的数组
char[] value;
//字符数组的字符个数
int count;
构造方法
- 无参
AbstractStringBuilder() {
}
- 有参
//为字符数组指定容量
AbstractStringBuilder(int capacity) {
value = new char[capacity];
}
length()
//返回字符个数
@Override
public int length() {
return count;
}
capacity()
//返回AbstractStringBuilder的容量(数组的容量)
public int capacity() {
return value.length;
}
扩容
/**
* 私有方法,扩容,扩大value数组容量,并拷贝数组元素
*/
private void ensureCapacityInternal(int minimumCapacity) {
// overflow-conscious code
if (minimumCapacity - value.length > 0) {
value = Arrays.copyOf(value,
newCapacity(minimumCapacity));
}
}
//调用私有扩容方法
public void ensureCapacity(int minimumCapacity) {
if (minimumCapacity > 0)
ensureCapacityInternal(minimumCapacity);
}
拼接
/**
* 私有方法,追加字符串
*/
public AbstractStringBuilder append(String str) {
if (str == null)
return appendNull();
int len = str.length();
//将value数组扩容
ensureCapacityInternal(count + len);
//调用Stirng类的getChars方法将str追加到末尾
str.getChars(0, len, value, count);
count += len;
//返回自身
return this;
}
//调用私有扩容方法
public AbstractStringBuilder append(Object obj) {
return append(String.valueOf(obj));
}
除了拼接字符串,AbstractStringBuilder还实现了拼接字符数组,基本数据类型等。
StringBuilder
在StringBuilder中,绝大部分的方法都是直接调用父类AbstractStringBuilder类的方法。
例如:
@Override
public StringBuilder append(String str) {
super.append(str);
return this;
}
StringBuffer
属性
// toString返回的最后一个值的缓存。 每当修改StringBuffer时清除。
private transient char[] toStringCache;
方法
和StringBuilder类似,StringBuffer大部分方法也都是直接调用父类AbstractStringBuilder类的方法的方法。
不同的是,StringBuffer是线程安全的。是因为 StringBuffer 类的 大部分方法都被 synchronized 修饰。
例如:
@Override
public synchronized StringBuffer append(String str) {
toStringCache = null;
super.append(str);
return this;
}
参考: