StringBuffer和StringBuilder源码分析

今天分析的两个类是:StringBuffer 和 StringBuilder。开篇前,先看看它们的继承层次:

<span style="color:#333333"><span style="color:#f8f8f2"><code class="language-java"><span style="color:#66d9ef"><span style="color:#f92672">public</span></span> <span style="color:#66d9ef"><span style="color:#f92672">final</span></span> <span style="color:#66d9ef"><span style="color:#f92672">class</span></span> <span style="color:#f8f8f2">StringBuffer</span> <span style="color:#66d9ef"><span style="color:#f92672">extends</span></span> <span style="color:#f8f8f2">AbstractStringBuilder</span>
<span style="color:#66d9ef"><span style="color:#f92672">implements</span></span> <span style="color:#f8f8f2">java</span><span style="color:#f8f8f2">.</span><span style="color:#f8f8f2">io</span><span style="color:#f8f8f2">.</span><span style="color:#f8f8f2">Serializable</span><span style="color:#f8f8f2">,</span> <span style="color:#f8f8f2">CharSequence</span> <span style="color:#f8f8f2">{</span><span style="color:#f8f8f2">.</span><span style="color:#f8f8f2">.</span><span style="color:#f8f8f2">.</span><span style="color:#f8f8f2">}</span>
<span style="color:#66d9ef"><span style="color:#f92672">public</span></span> <span style="color:#66d9ef"><span style="color:#f92672">final</span></span> <span style="color:#66d9ef"><span style="color:#f92672">class</span></span> <span style="color:#f8f8f2">StringBuilder</span> <span style="color:#66d9ef"><span style="color:#f92672">extends</span></span> <span style="color:#f8f8f2">AbstractStringBuilder</span>
<span style="color:#66d9ef"><span style="color:#f92672">implements</span></span> <span style="color:#f8f8f2">java</span><span style="color:#f8f8f2">.</span><span style="color:#f8f8f2">io</span><span style="color:#f8f8f2">.</span><span style="color:#f8f8f2">Serializable</span><span style="color:#f8f8f2">,</span> <span style="color:#f8f8f2">CharSequence</span> <span style="color:#f8f8f2">{</span><span style="color:#f8f8f2">.</span><span style="color:#f8f8f2">.</span><span style="color:#f8f8f2">.</span><span style="color:#f8f8f2">}</span></code></span></span>

    都继承了 AbstractStringBuilder ,实现了 Serializable 和 CharSequence 接口。final类型,不能再派生子类。

 

一.成员变量

    (1) char[] value;// 底层都是用字符数组char[]实现,存储字符串,默认的大小为16。在父类 AbstractStringBuilder 中定义的。String的value数组使用final修饰,不能变动,StringBuffer和StringBuilder的value数组没有final修饰,是可变的。 关于数组的大小,默认的初始化容量是16。这个数有木有想起了Map的实现子类的初始容量。假如初始化的时候,传入字符串,则最终的容量将是 (传入字符串的长度 + 16) 。 

    (2) private transient char[] toStringCache;// StringBuffer特有,缓存toString最后一次返回的值。 如果多次连续调用toString方法的时候由于这个字段的缓存就可以少了Arrays.copyOfRange的操作(每次调用其他的修改StringBuffer对象的方法时,这些方法的第一步都会先将toStringCache设置为null,详细参见源码) StringBuilder.toString()

<span style="color:#333333"><span style="color:#f8f8f2"><code class="language-java"> <span style="color:#66d9ef"><span style="color:#f92672">public</span></span> String <span style="color:#e6db74"><span style="color:#a6e22e">toString</span></span><span style="color:#f8f8f2"><span style="color:#f8f8f2">(</span></span><span style="color:#f8f8f2"><span style="color:#f8f8f2">)</span></span> <span style="color:#f8f8f2">{</span>
    <span style="color:slategray"><span style="color:#75715e">// Create a copy, don't share the array</span></span>
    <span style="color:#66d9ef"><span style="color:#f92672">return</span></span> <span style="color:#66d9ef"><span style="color:#f92672">new</span></span> String<span style="color:#f8f8f2">(</span>value<span style="color:#f8f8f2">,</span> <span style="color:#ae81ff"><span style="color:#ae81ff">0</span></span><span style="color:#f8f8f2">,</span> count<span style="color:#f8f8f2">)</span><span style="color:#f8f8f2">;</span>
 <span style="color:#f8f8f2">}</span></code></span></span>

StringBuffer.toString()

<span style="color:#333333"><span style="color:#f8f8f2"><code class="language-java"> <span style="color:#66d9ef"><span style="color:#f92672">public</span></span> <span style="color:#66d9ef"><span style="color:#f92672">synchronized</span></span> String <span style="color:#e6db74"><span style="color:#a6e22e">toString</span></span><span style="color:#f8f8f2"><span style="color:#f8f8f2">(</span></span><span style="color:#f8f8f2"><span style="color:#f8f8f2">)</span></span> <span style="color:#f8f8f2">{</span>
    <span style="color:#66d9ef"><span style="color:#f92672">if</span></span> <span style="color:#f8f8f2">(</span>toStringCache <span style="color:#f8f8f2">==</span> <span style="color:#f92672">null</span><span style="color:#f8f8f2">)</span> <span style="color:#f8f8f2">{</span><span style="color:slategray"><span style="color:#75715e">// toStringCache为空,第一次操作</span></span>
        toStringCache <span style="color:#f8f8f2">=</span> Arrays<span style="color:#f8f8f2">.</span><span style="color:#e6db74">copyOfRange</span><span style="color:#f8f8f2">(</span>value<span style="color:#f8f8f2">,</span> <span style="color:#ae81ff"><span style="color:#ae81ff">0</span></span><span style="color:#f8f8f2">,</span> count<span style="color:#f8f8f2">)</span><span style="color:#f8f8f2">;</span>
    <span style="color:#f8f8f2">}</span>
    <span style="color:#66d9ef"><span style="color:#f92672">return</span></span> <span style="color:#66d9ef"><span style="color:#f92672">new</span></span> String<span style="color:#f8f8f2">(</span>toStringCache<span style="color:#f8f8f2">,</span> <span style="color:#ae81ff"><span style="color:#f92672">true</span></span><span style="color:#f8f8f2">)</span><span style="color:#f8f8f2">;</span><span style="color:slategray"><span style="color:#75715e">// 使用缓存的toStringCache,实际只传递了引用,没有复制操作</span></span>
 <span style="color:#f8f8f2">}</span></code></span></span>

    String 提供了一个保护类型的构造方法。目前不支持使用false,只使用true。那么可以断定,加入这个share的只是为了区分于String(char[] value)方法,不加这个参数就没办法定义这个函数,只有参数不同才能进行重载。那么,第二个区别就是具体的方法实现不同。这里直接将value的引用赋值给String的value。那么也就是说,这个方法构造出来的String和参数传过来的char[] value共享同一个数组。作用的话,肯定是性能好一点。假如把该方法改为public,而不是protected的话,对外开放访问,就可以通过修改数组的引用来破坏String的不可变性。

原文链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值