偶尔发现,Jdk1.4 和 jdk1.5 中的 StringBuffer有些不同,做了个简单调查
toString() 方法 <o:p> </o:p>
jdk1.4 中: StringBuffer 的 toString() 是这样实现的: <o:p> </o:p>
public String toString() { <o:p> </o:p>
return new String( this ); <o:p> </o:p>
} <o:p> </o:p>
<o:p> </o:p>
继续跟踪到 String 的构造函数: <o:p> </o:p>
public String (StringBuffer buffer) { <o:p> </o:p>
synchronized (buffer) { <o:p> </o:p>
buffer.setShared(); <o:p> </o:p>
this . value = buffer.getValue(); <o:p> </o:p>
this . offset = 0; <o:p> </o:p>
this . count = buffer.length(); <o:p> </o:p>
} <o:p> </o:p>
} <o:p> </o:p>
没有重新 new 内存空间,是共享的,这个时候首先想到的问题,如果 StringBuffer 变了, String 怎么办 <o:p> </o:p>
<o:p> </o:p>
继续看 StringBuffer 的操做,例如 deleteCharAt<o:p></o:p> ()
public synchronized StringBuffer deleteCharAt( int index) { <o:p> </o:p>
if ((index < 0) || (index >= count )) <o:p> </o:p>
throw new StringIndexOutOfBoundsException(); <o:p> </o:p>
if ( shared ) <o:p> </o:p>
copy(); <o:p> </o:p>
System.arraycopy( value , index+1, value , index, count -index-1); <o:p> </o:p>
count --; <o:p> </o:p>
return this ; <o:p> </o:p>
} <o:p> </o:p>
<o:p> </o:p>
当 StringBuffer 改变的时候 , 判断了是否 shared, 然後决定是否 copy<o:p></o:p>
而且为了避免同步问题,把方法做成同步的 <o:p> </o:p>
<o:p> </o:p>
<o:p> </o:p>
<o:p> </o:p>
<o:p> </o:p>
jdk1.5<o:p></o:p>
public synchronized String toString() { <o:p> </o:p>
return new String( value , 0, count ); <o:p> </o:p>
}<o:p></o:p>
跟踪进入 String<o:p></o:p>
public String( char value[], int offset, int count) { <o:p> </o:p>
if (offset < 0) { <o:p> </o:p>
throw new StringIndexOutOfBoundsException(offset); <o:p> </o:p>
} <o:p> </o:p>
if (count < 0) { <o:p> </o:p>
throw new StringIndexOutOfBoundsException(count); <o:p> </o:p>
} <o:p> </o:p>
// Note: offset or count might be near -1>>>1. <o:p> </o:p>
if (offset > value. length - count) { <o:p> </o:p>
throw new StringIndexOutOfBoundsException(offset + count); <o:p> </o:p>
} <o:p> </o:p>
char [] v = new char [count]; <o:p> </o:p>
System.arraycopy(value, offset, v, 0, count); <o:p> </o:p>
this . offset = 0; <o:p> </o:p>
this . count = count; <o:p> </o:p>
this . value = v; <o:p> </o:p>
}<o:p></o:p>
重新分配了内存空间 <o:p> </o:p>
<o:p> </o:p>
再来看看 StringBuffer 的 deleteCharAt<o:p></o:p>
public synchronized StringBuffer deleteCharAt( int index) { <o:p> </o:p>
super .deleteCharAt(index); <o:p> </o:p>
return this ; <o:p> </o:p>
} <o:p> </o:p>
<o:p> </o:p>
<o:p> </o:p>
<o:p> </o:p>
<o:p> </o:p>
<o:p> </o:p>
<o:p> </o:p>
<o:p> </o:p>
有了继承关系,先不管,继续 <o:p> </o:p>
public AbstractStringBuilder deleteCharAt( int index) { <o:p> </o:p>
if ((index < 0) || (index >= count )) <o:p> </o:p>
throw new StringIndexOutOfBoundsException(index); <o:p> </o:p>
System.arraycopy( value , index+1, value , index, count -index-1); <o:p> </o:p>
count --; <o:p> </o:p>
return this ; <o:p> </o:p>
} <o:p> </o:p>
不需要判断,也不需要 copy 了 <o:p> </o:p>
<o:p> </o:p>
既然看到了继承关系,那我们先看一下这个继承关系,再得出结论 <o:p> </o:p>
发现 <o:p> </o:p>
abstract class AbstractStringBuilder implements Appendable, CharSequence <o:p> </o:p>
然後 <o:p> </o:p>
public final class StringBuffer <o:p> </o:p>
extends AbstractStringBuilder <o:p> </o:p>
implements java.io.Serializable, CharSequence <o:p> </o:p>
<o:p> </o:p>
public final class StringBuilder <o:p> </o:p>
extends AbstractStringBuilder <o:p> </o:p>
implements java.io.Serializable, CharSequence<o:p></o:p>
<o:p> </o:p>