JDK1.6字串拼接自動生成StringBuilder
JDK1.6字串拼接
從JAVA誕生那天起,稍微“有些水平”的程式設計師都被告知,如果有大量的字串連結,請不要使用字串相加,而應該使用StringBuffer的append操作然後toString().
到了JAVA5,我們又被告訴知,StringBuilder是StringBuffer的非同步版,所以絕對大多數時候我們“更”可以用StringBuilder來代替加操作。因為一個可能被多執行緒訪問的例項欄位的StringBuffer操作的情況很少,和在方法中呼叫字串連結相比1%都不到。
但是到了JAVA6,因為編譯器“始終”把字串的+連結編譯成StringBuilder,所以在99%的情況,我們應該使用加操作。
理由是:
1.用加操作比其它操作看起來直觀,寫起來省事,JAVA6之前,即使明知道有效能問題我們還會在一些時候全使用+連結,根本原因當然是這種寫法直觀,簡單。
publicvoid appendStr(String art) {
String show = "<" + art + ">";
}
//請注意,這裡的例子只是為了說明"+"寫法直觀,並不是說只有常量字串相加(常量字串其實直接編譯成一個字串而不是append了)JAVA6才優化,那是之前的事,對於JAVA6,只要有是字串操作的的+連結(第一個變數或常量是字串),後面不管是常量還是變數,都會進行編譯優化
public void appendStr(String art)
{
String show = (new StringBuilder("<")).append(art).append(">").toString();
}
誰要說第二種試方式美觀寫起來爽我一定當面抽他。打到他腦子正常為止。
2.我們有時還自覺不自覺地使用StringBuffer,而JAVA6總是把第一種形式優化為StringBuilder,在99%的情況下效能更好,除非你需要一個被多執行緒訪問的例項欄位操作。
3.特別是,有時我們自己寫StringBuilder時,sb.append(line);後來想在前後加一個"<",">",於是很懶地寫成sb.append("<"+line+">");這種情況非常多,但這樣情況是先生成一個StringBuilder計算"<"+line+">",然後toString()
StringBuilder所append,還不如全部加操作讓編譯器用一個StringBuilder來append.
當然,迴圈中加操作千萬不要這麼做(這種需求除了測試,實際應用可能是萬分之一的機會吧?),編譯器雖然會優化編譯,但它是在迴圈內部生成 StringBuilder而不是在外部。這種情況一定要自己在外部手工定義StringBuilder而不能依賴編譯器了。但絕對多數情況,也就是 99%的情況我們是 str = "axman" + new Object() +1 + "good"+.......這種方式,完全可以信任編譯器來優化。
另外只有兩個字串連結時請使用concat.
For迴圈不要再迴圈裡面+號拼接字串,因為會在迴圈裡面生成StringBuilder.
public void appendStrForOwnerStringBuffer() {
StringBuffer sb =new StringBuffer();
for (int i = 0; i< 10; i++) {
sb.append("<").append(i).append("><br>");
}
}
public voidappendstrForJVMCreateStringBuffer() {
String show ="";
for (int i = 0; i< 10; i++) {
show +="<" + i + "><br>";
}
}
Xjad反編譯:
public voidappendStrForOwnerStringBuffer()
{
StringBuffer sb =new StringBuffer();
for (int i = 0; i< 10; i++)
sb.append("<").append(i).append("><br>");
}
public voidappendstrForJVMCreateStringBuffer()
{
String show ="";
for (int i = 0; i< 10; i++)
show = (new StringBuilder(String.valueOf(show))).append("<").append(i).append("><br>").toString();
}