偶尔发现,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()
的实现呢
暂时还没找到好的原因,大部份原因都比较牵强。