在String對象中有個構造函數是直接接受StringBuffer的
程序如下
public String (StringBuffer buffer) {
synchronized(buffer) {
buffer
setShared();
this
value = buffer
getValue();
this
offset =
;
unt = buffer
length();
}
}
在StringBuffer中
final char[] getValue() { return value; }
很明顯的
這個構造函數直接把StringBuffer的char[]數組返回給了String對象
也就是現在新生成的String和StringBuffer共用同一個char[]數組
但是下面的程序為什麼會打印出以下結果呢
StringBuffer sb = new StringBuffer(
abc
);
System
out
println(
StringBuffer:
+ sb
toString());
String s = new String(sb);
System
out
println(
String:
+ s);
sb
append(
);
System
out
println(
StringBuffer:
+ sb);
System
out
println(
String:
+ s);
/////////////////////////////////////////////////////////////////////
StringBuffer: abc
String: abc
StringBuffer: abc
String: abc
分析
這個問題的核心答案在 unt = buffer
length() 這句話上
這句話的意思是String中的count的大小為這個char[]數組中實際含有的字符的個數
而不是這個數組的大小
所以在打印的時候對於上面的String對象
只會打印
個字符
而不是六個字符!!
新的問題
如果我從StringBuffer中刪除了一個字符
那麼String對象也應該受到影響了?但是為什麼實際上這個String沒有發生變化呢?問題的答案在buffer
setShared()上
這句話的含義就是告訴這個StringBuffer
有其它的String對象與它共享它的char[]數組
這個時候
當它進行delete
insert等操作的時候
它會新生成一個char[]數組
然後再進行操作
所以這個時候String和StringBuffer就不共享同一個數組了
String自然也就不會受到影響了
為什麼要用這麼復雜的方法呢?答案是
節省內存資源
可以想想
我們在程序中使用最頻繁的對象都有哪些?答案肯定包含String
而我們知道
在拼裝一個String的時候
使用StringBuffer效率最高
所以我們會先用StringBuffer動態的拼裝好一個字符串
然後再把它轉化成String對象
這個時候就會突顯這種方式的經典之處了
下面是StringBuffer的toString()方法
public String toString() {
return new String(this);
}
From:http://tw.wingwit.com/Article/program/Java/hx/201311/26156.html