偶尔发现,Jdk1.4 和 jdk1.5 中的 StringBuffer有些不同,做了个简单调查
toString() 方法
jdk1.4 中: StringBuffer 的 toString() 是这样实现的:
public String toString() {
return new String( this );
}
继续跟踪到 String 的构造函数: public String (StringBuffer buffer) { synchronized (buffer) { buffer.setShared(); this . value = buffer.getValue(); this . offset = 0; this . count = buffer.length(); } }
没有重新 new 内存空间,是共享的,这个时候首先想到的问题,如果 StringBuffer 变了, String 怎么办?
继续看 StringBuffer 的操做,例如 deleteCharAt ()
public synchronized StringBuffer deleteCharAt( int index) { if ((index < 0) || (index >= count )) throw new StringIndexOutOfBound***ception(); if ( shared ) copy(); System.arraycopy( value , index+1, value , index, count -index-1); count --; return this ; }
当 StringBuffer 改变的时候 , 判断了是否 shared, 然後决定是否 copy
而且为了避免同步问题,把方法做成同步的
jdk1.5 :
public synchronized String toString() { return new String( value , 0, count ); }
跟踪进入 String
public String( char value[], int offset, int count) { if (offset < 0) { throw new StringIndexOutOfBound***ception(offset); } if (count < 0) { throw new StringIndexOutOfBound***ception(count); } // Note: offset or count might be near -1>>>1. if (offset > value. length - count) { throw new StringIndexOutOfBound***ception(offset + count); } char [] v = new char [count]; System.arraycopy(value, offset, v, 0, count); this . offset = 0; this . count = count; this . value = v; } 重新分配了内存空间。
再来看看 StringBuffer 的 deleteCharAt
public synchronized StringBuffer deleteCharAt( int index) { super .deleteCharAt(index); return this ; }
有了继承关系,先不管,继续
public AbstractStringBuilder deleteCharAt( int index) { if ((index < 0) || (index >= count )) throw new StringIndexOutOfBound***ception(index); System.arraycopy( value , index+1, value , index, count -index-1); count --; return this ; }
不需要判断,也不需要 copy 了
[ 本帖最后由 hexq 于 2006-12-7 12:14 编辑 ] |