偶爾發現,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
StringIndexOutOfBoundsException();
??????
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
StringIndexOutOfBoundsException(offset);
??????? }
???????
if
(count < 0) {
???????????
throw
new
StringIndexOutOfBoundsException(count);
??????? }
???????
// Note: offset or count might be near -1>>>1.
???????
if
(offset > value.
length
- count) {
???????????
throw
new
StringIndexOutOfBoundsException(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
StringIndexOutOfBoundsException(index);
?????? System.arraycopy(
value
, index+1,
value
, index,
count
-index-1);
??????
count
--;
???????
return
this
;
}
不需要判斷,也不需要
copy
了
?
既然看到了繼承關系,那我們先看一下這個繼承關系,再得出結論
發現
abstract
class
AbstractStringBuilder
implements
Appendable, CharSequence
然後
public
final
class
StringBuffer
???
extends
AbstractStringBuilder
???
implements
java.io.Serializable, CharSequence
?
public
final
class
StringBuilder
???
extends
AbstractStringBuilder
???
implements
java.io.Serializable, CharSequence
?
看一下
document
的解釋
?
?
現在可以大概做一下總結了:
首先
toString()
方法
1.4
是不
new
新空間的,把
new
新空間推后到
StringBuffer
再次被更改,提高了性能。
StirngBuffer
的一些方法是同步的
?
Jdk1.5
區別對待,加入了繼承關系,加入了
StringBuilder
StringBuffer
是線程安全的,同步的方法
StringBuilder
的是線程不安全,非同步的
在同步方面
jdk1.5
提供了更多的選擇。
?
疑問,為什么
jdk1.5
中,
StringBuffer
改變了
toString()
的實現呢
暫時還沒找到好的原因,大部份原因都比較牽強。