当前位置: 代码迷 >> 综合 >> JDK8源码研究(二):AbstractStringBuilder StringBuilder StringBuffer
  详细解决方案

JDK8源码研究(二):AbstractStringBuilder StringBuilder StringBuffer

热度:99   发布时间:2023-10-14 02:05:55.0

JDK8源码研究(二):AbstractStringBuilder StringBuilder StringBuffer

首先来看AbstractStringBuilder,实现了CharSequence,该接口也是String的接口,定义了字符串的方法,还有Appendable接口,该接口定义了append方法以及几个append方法的重载。再来看AbstractStringBuilder类的私有属性,和String类比较相近,比String少了个hash属性,AbstractStringBuilder类没有重写Object父类的hashCode方法,但比String类多了一个count属性,因为AbstractStringBuilder类是可变字符串,所以count属性来记录实际使用了多少长度。AbstractStringBuilder维护了一组char数组来记录字符串,当添加新字符串进来时就会进行一次扩容判断。

JDK8源码研究(二):AbstractStringBuilder StringBuilder StringBuffer

AbstractStringBuilder提供了一个输入容量大小的构造方法,其私有属性value这个char数组的长度会被赋值。

JDK8源码研究(二):AbstractStringBuilder StringBuilder StringBuffer

再来看看我们常用的append方法,看红线部分,该方法为AbstractStringBuilder提供的扩容逻辑,每次添加字符串都会进行一次扩容判断。

JDK8源码研究(二):AbstractStringBuilder StringBuilder StringBuffer

JDK8源码研究(二):AbstractStringBuilder StringBuilder StringBuffer

再来看其具体的扩容逻辑,如果当前value数据的长度小于需要的最小长度,就会进行一次扩容,先将现有的数组长度乘以二倍再加2,如果还是小于最小需要的长度,则扩容的长度为传入的minCapacity,即最小需要的长度。最后还会判断最小需要的长度是否已经大于数组长度的最大值获取小于等于0,如果是的话就会取最大数组长度。

再来看StringBuffer类

JDK8源码研究(二):AbstractStringBuilder StringBuilder StringBuffer

该类为线程安全的可变字符串类,其内部维护了一个不可变数组缓存,无参构造方法会调用父类传入容量大小的构造方法,构建一个长度为16的char数组。

JDK8源码研究(二):AbstractStringBuilder StringBuilder StringBuffer

该类大量的操作方法都加了synchronized锁,并且对字符串进行写操作的时候回删除toStringCache缓存,toString方法会先将父类的数组拷贝到定长的toStringCache属性中,下次会直接使用toStringCache属性来构建String类。

JDK8源码研究(二):AbstractStringBuilder StringBuilder StringBuffer

StringBuilder差不多是StringBuffer的翻版,只是StringBuilder是线程不安全的,方法中没有使用synchronized锁,所以效率更高,也没有引用缓存,感觉StringBuffer的缓存在操作频繁时候反而会降低类的效率,因为每次写操作都需要清空一次缓存。

  相关解决方案