在 Java String类源码阅读笔记 里学习了String类的源码,StringBuilder、StringBuffer是经常拿来和String类做对比的两个类,可谓是“爱恨纠缠” ,这里我们继续学习这两个类的源码。
本文基于jdk1.8。
StringBuilder/StringBuffer继承关系
StringBuilder、StringBuilder具有相同的继承关系,都继承自AbstractStringBuilder类,实现了CharSequence接
口。
StringBuilder继承关系
StringBuffer继承关系
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; }