一. 前言
StringBuffer 和 StringBuilder的底层都是使用数组存储
结构图:
二. 区别
-
他们两个的区别主要就在于 StringBuffer 的方法上基本都加了
synchronized
关键字,保证了线程安全,当然也降低了性能.
而 StringBuilder 的方法没有加synchronized
关键字. -
StringBuffer 会缓存最后一次使用 toString 方法的返回值
-
StringBuffer 会重写一些父类方法,实现为
super.xx()
直接调用父类方法.但是重写的方法加上了synchronized
关键字.也就保证了在调用了父类的方法时也是线程安全的.其他方面基本一直.来让我往下观看相同的地方
二. 构造器
有三种构造器:
- 无参数构造器
- 有初始字符串构造器
- 有初始容量大小构造器
在 new StringBuffer ()
时,创建的初始数组在没有设置大小时,为 16, 如果设置了初始字符串,则会在字符串的长度加上 16
StringBuffer 对象有两个属性(准确说是父类 AbstractStringBuilder 的属性).char[] value;
和 int count;
;前者是对象底层的数组(包含附加的缓冲空间),后者是数组中的字符数量; value > count
四. append 方法
- 在每次调用时会清除最后一次调用
toString()
时缓存的结果(StringBuffer 专属) - 使用 append 方法时,如果传入的对象为 null, 则会变成添加字符串 'null’的操作
- 在添加元素前会判断,添加对象的长度和 count 相加是否小于 value,length .如果不是则扩充
- 将添加对象的字符添加到 value 中,具体调用的是本地方法,将添加对象的字符数组拷贝到 value 数组的指定位置
- 将 count 更改为加上添加对象的长度的值
五. StringBuffer 和 StringBuilder 的扩充
- 先将 value.length 进行位移运算向左移动一位,然后 +2
- 判断 value.length 位移后的长度和 count + 增加新元素的长度大小.如果小于 count + 增加新元素的长度大小,则数组长度设置为 count + 增加新元素的长度大小,
- 判断长度是否大于 MAX_ARRAY_SIZE ( 值为
Integer.MAX_VALUE - 8
)或长度为负数 (即溢出) 都会判断是否大于Integer.MAX_VALUE
如果大于则报错,小于则判断是否大于 MAX_ARRAY_SIZE ,如果大于则扩充到该值,如果小于则为 MAX_ARRAY_SIZE