StringBuffer 和Stringbuilder源码分析

首先看一下他们的继承关系
 
这个两个对象都继承了AbstractStringBuilder抽象类。
 
1.他们的实现方式都一样的,唯一区别的StringBuffer在多线程的时候是保证了数据安全,每个方法都加上synchronize关键字,让线程同步。
 
2.从初始化开始看StringBuffer 有三个构造函数。
(1) 第一个是无参的构造函数 ,默认调用AbstractStringBuilder的构造函数,将一个大小为16长度的char数组赋值给父类的value值。
(2)第二个是int类型的参数,表示将一个大小为int参数的char数组赋值给父类的value值。
(3)第三个是String类型。表示将一个大小为16的加上参数字符串长度的大小的char数组赋值给value值。
3.StringBuffer和StringBuilder类里我们最常用的事append方法,都在父类里实现了。我们最常用的是append一个字符串。
初始化父类的value值是一个大小为16的char数组,count为0.
当我们append一个字符串时,默认调用父类的append方法。源码如下:
 
count值是append的累加。也就是当前加入的字符串的长度。每次累加都拼接在后面。这里用了getChars()实现。这里主要是看ensureCpacityInternel() 字面上检查容量是否正常。源码如下:
意思很明显,初始化的长度不够了要进行扩充了,将原来的value值放在新的char数组同时又赋给value值。源码如下:
 
大意为: 把初始化的长度扩充为左位移运算1 也就是乘以2再加2的长度。如果扩从的长度还是小于你入参的长度 那就入参的长度当做我char数组的长度。最后返回的时候又校验长度如果小于等于0或者入参长度大于定义的默认最大长度Integer.MAX_VALUE - 8,那就抛出内存溢出异常。
 
总结:
1.StringBuffer和StringBuilder append()的时候参数的大小是有限制的。
2.构造函数的大小将决定char数组扩容的基数。

猜你喜欢

转载自www.cnblogs.com/Seeasunnyday/p/9101402.html