概述
源码开头注释说到,StringBuffer是一个线程安全的,可变的字符串序列。可在多线程中使用。
继承关系
继承自 AbstractStringBuilder 类 实现了 java.io.Serializable, CharSequence 接口
成员属性
private transient char[] toStringCache;
存储上一次ToString()得到的值,当StringBuffer被改变的时候,会被清除。其实是为了节省计算时间,不重复消耗计算能力。
构造器
最明显的特点就是新建一个StringBuffer后,会将容量指定为实际容量+16。
public StringBuffer() {
super(16);
}
public StringBuffer(int capacity) {
super(capacity);
}
public StringBuffer(String str) {
super(str.length() + 16);
append(str);
}
public StringBuffer(CharSequence seq) {
this(seq.length() + 16);
append(seq);
}
关键方法
+ length()
获取StringBuffer实际字符的长度 继承重写了父类AbstractStringBuilder的length()方法。 方法体一样,仅仅是添加了 synchronized 修饰符。
@Override
public synchronized int length() {
return count;
}
+ capacity()
获取当前 StringBuffer 的容量 继承重写了父类 AbstractStringBuilder 的 capacity()方法。 方法体一样,仅仅是添加了 synchronized 修饰符。
@Override
public synchronized int capacity() {
return value.length;
}
+ ensureCapacity()
重写父类方法,使用父类的方法ensureCapacity进行扩容, 增加了synchronized修饰符。
@Override
public synchronized void ensureCapacity(int minimumCapacity) {
super.ensureCapacity(minimumCapacity);
}
+ trimToSize()
重写父类方法,使用父类的方法trimToSize去除字符串末尾的空格,增加了synchronized修饰符。
@Override
public synchronized void trimToSize() {
super.trimToSize();
}
+ setLength()
重写父类方法设置长度, 增加了synchronized修饰符。
@Override
public synchronized void setLength(int newLength) {
toStringCache = null;
super.setLength(newLength);
}
+ charAt()
返回指定位置处的字符
@Override
public synchronized char charAt(int index) {
if ((index < 0) || (index >= count))
throw new StringIndexOutOfBoundsException(index);
return value[index];
}
+ append()
将指定对象添加到StringBuffer末尾,有很多重载方法,适应了不同的数据类型。
@Override
public synchronized StringBuffer append(Object obj) {
toStringCache = null;
super.append(String.valueOf(obj));
return this;
}
+ delete()
删除指定位置范围内的字符
@Override
public synchronized StringBuffer delete(int start, int end) {
toStringCache = null;
super.delete(start, end);
return this;
}
+ replace()
将指定位置范围处的字符替换为目标字符串
@Override
public synchronized StringBuffer replace(int start, int end, String str) {
toStringCache = null;
super.replace(start, end, str);
return this;
}
+ substring()
获取子串,从start索引开始到末尾。
@Override
public synchronized String substring(int start) {
return substring(start, count);
}
+ insert()
将字符串插入到指定位置。有很多重载方法
@Override
public synchronized StringBuffer insert(int offset, String str) {
toStringCache = null;
super.insert(offset, str);
return this;
}
+ indexOf()
计算字符串第一次出现的位置。
@Override
public int indexOf(String str) {
// Note, synchronization achieved via invocations of other StringBuffer methods
return super.indexOf(str);
}
+ lastIndexOf()
计算字符串最后一次出现的位置。
@Override
public int lastIndexOf(String str) {
// Note, synchronization achieved via invocations of other StringBuffer methods
return lastIndexOf(str, count);
}
+ reverse()
返回StringBuffer的倒序排列。
@Override
public synchronized StringBuffer reverse() {
toStringCache = null;
super.reverse();
return this;
}
实现原理
- 底层的存储结构,是和父类AbstractStringBuilder一样的,都是字符数组char[] value。
- 实现线程安全的主要途径,就是给对应的方法增加了synchronized修饰符。
常见问题
synchronized 的使用?
关键字synchronized可以保证在同一时刻,只有一个线程可以执行某个方法或某个代码块,同时synchronized可以保证一个线程的变化可见(可见性),即可以代替volatile。 Java中每一个对象都可以作为锁,这是synchronized实现同步的基础: 普通同步方法(实例方法),锁是当前实例对象 ,进入同步代码前要获得当前实例的锁 静态同步方法,锁是当前类的class对象 ,进入同步代码前要获得当前类对象的锁 同步方法块,锁是括号里面的对象,对给定对象加锁,进入同步代码库前要获得给定对象的锁。
相关阅读
JDK1.8源码解读之 AbstractStringBuilder
希望和大家多多交流
我16年毕业以后,做的是前端,目前打算深入学习java开发。内容有任何问题,欢迎各位小伙伴们指正,也希望小伙伴们给我点赞和关注,给我留言,一起交流讨论,共同进步。