此时此刻,突然对 StringBuffer
产生了些许'兴趣',本着给大家分享些基础知识,同时巩固下自己的基础知识的美好意愿,给大家写了这篇帖子(其实就是闲的哈哈哈)。好了废话不多说,进入正题。
像 String
, StringBuffer
, StringBuilder
这三个的基本介绍就不多说了,相信大家都清楚,不清楚的可以前往某歌或某度查询(●'◡'●)。 我们先来看下StringBuffer内部的一个大概情况:
可以看到我们的 StringBuffer
继承了 AbstractStringBuilder
类,实现了 Serializable
接口和 CharSequence
接口,并且里面的方法都加了 Synchronized
关键字,说明 StringBuffer
是线程安全的。
AbstractStringBuilder
中一个char类型的字符数组用来存储,count就是用来记录实际字符数的,后面也会讲到。
我们在看下他初始化方法,这里只列举了一部分,通过这些构造方法看出,都是调用父类的构造方法给父类的char类型数组赋值,并且默认不带参数的长度为16,如果带参数的话,就为参数长度加上16。
这有个需要注意的点,就是如果我们通过无参构造创建一个空的StringBuffer
的变的话,输出他的长度是0而不是16,这就和他父类的count属性有关了。官方注释写到这是count是记录字符数,也就是实际有多少个元素。看下
StringBuffer
的
length()
方法,并不是直接返回
value.length()
的,而是返回count的值。
那就有人问了(其实没人想问),那的字符数组满了怎么办?我们自己看他底层的扩容方法,那要扩容的话肯定是在往里面加的时候做的,这时候我们直接看到append()
方法,他里面有很多重载的方法,这里我们就拿参数类型为
String
的举例:
可以看到,最终还是调用的父类的方法:
进入方法,先判断是否为空,然后获取我们添加的字符串长度,在调用ensureCapacityInternal()
方法,把我们的要添加的字符串长度和原字符数组实际个数相加做为形参添加进去,我们可以看下这个方法:先会判断是否需要扩容,然后进行下一步操作
如果需要扩容的话,就会进入newCapacity()
方法:
这里,我们就很清楚的看到了StringBuffer
的扩容是在原来的继承上扩容1倍在加上2,然后返回新的长度,最终通过
Arrays.copyOf()
完成扩容。回到
append()
方法可以看到,在最后的时候对count的值进行了增加,而这个值也是字符数组中实际数量的值。
但在实际开发的时候我还是推荐大家尽量少进行扩容操作,因为每次扩容都需要进行复制,对效率会有所影响。所以推荐大家在创建 StringBuffer
的时候就使用构造器对长度进行初始化。
好了,以上就是这次带大家简单了解了下 StringBuffer
的一些内部情况,我们下篇再见哦!