new String("value") 與 String string += "value" 的問題
環(huán)境: JDK6.0 Jad1.5.8(Java反編譯工具)
先看測試代碼與問題:
看反編譯結(jié)果:
先看測試代碼與問題:
public class StringObjectValueStack {
/*
* new String("value") 到底有幾個(gè)對(duì)象?
*/
public void methodString () {
String object = new String("value");
}
/*
* 為什么 String += "line"; 效率低下?
*/
public void methodManyString () {
String manyObject = "" ;
for (int index = 0 ; index < 10 ; index ++) {
manyObject += "line" ;
}
}
/*
* 為什么要用StringBuffer呢?
*/
public void methodStringBuffer () {
StringBuffer stringBuffer = new StringBuffer() ;
for (int index = 0 ; index < 10 ; index ++) {
stringBuffer.append("line") ;
}
}
/*
* 為什么要用StringBuilder呢?
*/
public void methodStringBuilder () {
StringBuilder stringBuilder = new StringBuilder() ;
for (int index = 0 ; index < 10 ; index ++) {
stringBuilder.append("line") ;
}
}
}
/*
* new String("value") 到底有幾個(gè)對(duì)象?
*/
public void methodString () {
String object = new String("value");
}
/*
* 為什么 String += "line"; 效率低下?
*/
public void methodManyString () {
String manyObject = "" ;
for (int index = 0 ; index < 10 ; index ++) {
manyObject += "line" ;
}
}
/*
* 為什么要用StringBuffer呢?
*/
public void methodStringBuffer () {
StringBuffer stringBuffer = new StringBuffer() ;
for (int index = 0 ; index < 10 ; index ++) {
stringBuffer.append("line") ;
}
}
/*
* 為什么要用StringBuilder呢?
*/
public void methodStringBuilder () {
StringBuilder stringBuilder = new StringBuilder() ;
for (int index = 0 ; index < 10 ; index ++) {
stringBuilder.append("line") ;
}
}
}
看反編譯結(jié)果:
public class StringObjectValueStack {
public StringObjectValueStack() {
// 0 0:aload_0
// 1 1:invokespecial #8 <Method void Object()>
// 2 4:return
}
public void methodString() {
String object = new String("value");
// 0 0:new #15 <Class String> 創(chuàng)建了一個(gè)實(shí)例對(duì)象 new String()
// 1 3:dup
// 2 4:ldc1 #17 <String "value"> 創(chuàng)建了第二個(gè)實(shí)例對(duì)象
// 上面的 “value” 雙引號(hào)的字符常量 第一次創(chuàng)建在 <字符常量緩沖區(qū)(Data Segment)> 中
// 下次再發(fā)現(xiàn)調(diào)用 "value" , 直接去 Data Segment 中拿值 , 不再新建
// 3 6:invokespecial #19 <Method void String(String)>
// 4 9:astore_1
// 5 10:return
// 至此共創(chuàng)建了兩個(gè)對(duì)象
}
public void methodManyString() {
String manyObject = "";
// 0 0:ldc1 #25 <String "">
// 1 2:astore_1
for(int index = 0; index < 10; index++)
//* 2 3:iconst_0
//* 3 4:istore_2
//* 4 5:goto 31
manyObject = (new StringBuilder(String.valueOf(manyObject))).append("line").toString();
// 5 8:new #27 <Class StringBuilder> 在 循環(huán)體內(nèi) 創(chuàng)建StringBuilder對(duì)象
// 雖然代碼為 String += "line" ; 但編譯器實(shí)際創(chuàng)建的還是StringBuilder對(duì)象來處理字符串
// 注意 JDK1.4 版本以前,編譯器 實(shí)際調(diào)用的是StringBuffer, 直到 JDK1.5以后,底層用StringBuilder代替
// 6 11:dup
// 7 12:aload_1
// 8 13:invokestatic #29 <Method String String.valueOf(Object)>
// 9 16:invokespecial #33 <Method void StringBuilder(String)>
// 10 19:ldc1 #34 <String "line">
// 如果 <字符常量緩沖區(qū)(Data Segment)> 沒有 "line" 的串對(duì)象,則創(chuàng)建了一個(gè)對(duì)象,以后每循環(huán)一次重復(fù)使用,不再新建
// 11 21:invokevirtual #36 <Method StringBuilder StringBuilder.append(String)>
// 12 24:invokevirtual #40 <Method String StringBuilder.toString()>
// 13 27:astore_1
// 14 28:iinc 2 1
// 15 31:iload_2
// 16 32:bipush 10
// 17 34:icmplt 8
// 18 37:return
// 至此,使用 String string += "line" ; 在循環(huán)體中,循環(huán)多少次,就創(chuàng)建多少個(gè)全新的StringBuilder對(duì)象
}
public void methodStringBuffer() {
StringBuffer stringBuffer = new StringBuffer();
// 0 0:new #48 <Class StringBuffer> 新建 StringBuffer 對(duì)象
// 1 3:dup
// 2 4:invokespecial #50 <Method void StringBuffer()>
// 3 7:astore_1
for(int index = 0; index < 10; index++)
//* 4 8:iconst_0
//* 5 9:istore_2
//* 6 10:goto 23
stringBuffer.append("line"); // 只是調(diào)用 StringBuffer 的 append 方法 壘加 字符串 并未創(chuàng)建新對(duì)象
// 7 13:aload_1
// 8 14:ldc1 #34 <String "line">
// 如果 <字符常量緩沖區(qū)(Data Segment)> 沒有 "line" 的串對(duì)象,則創(chuàng)建了一個(gè)對(duì)象,以后每循環(huán)一次重復(fù)使用,不再新建
// 9 16:invokevirtual #51 <Method StringBuffer StringBuffer.append(String)>
// 10 19:pop
// 11 20:iinc 2 1
// 12 23:iload_2
// 13 24:bipush 10
// 14 26:icmplt 13
// 15 29:return
// 至次,只創(chuàng)建了一個(gè)StringBuffer對(duì)象
}
public void methodStringBuilder() {
StringBuilder stringBuilder = new StringBuilder();
// 0 0:new #27 <Class StringBuilder> 新建 StringBuilder 對(duì)象
// 1 3:dup
// 2 4:invokespecial #57 <Method void StringBuilder()>
// 3 7:astore_1
for(int index = 0; index < 10; index++)
//* 4 8:iconst_0
//* 5 9:istore_2
//* 6 10:goto 23
stringBuilder.append("line"); // 只是調(diào)用 StringBuilder 的 append 方法 壘加 字符串 并未創(chuàng)建新對(duì)象
// 7 13:aload_1
// 8 14:ldc1 #34 <String "line">
// 如果 <字符常量緩沖區(qū)(Data Segment)> 沒有 "line" 的串對(duì)象,則創(chuàng)建了一個(gè)對(duì)象,以后每循環(huán)一次重復(fù)使用,不再新建
// 9 16:invokevirtual #36 <Method StringBuilder StringBuilder.append(String)>
// 10 19:pop
// 11 20:iinc 2 1
// 12 23:iload_2
// 13 24:bipush 10
// 14 26:icmplt 13
// 15 29:return
// 至次,只創(chuàng)建了一個(gè)StringBuilder對(duì)象
}
}
public StringObjectValueStack() {
// 0 0:aload_0
// 1 1:invokespecial #8 <Method void Object()>
// 2 4:return
}
public void methodString() {
String object = new String("value");
// 0 0:new #15 <Class String> 創(chuàng)建了一個(gè)實(shí)例對(duì)象 new String()
// 1 3:dup
// 2 4:ldc1 #17 <String "value"> 創(chuàng)建了第二個(gè)實(shí)例對(duì)象
// 上面的 “value” 雙引號(hào)的字符常量 第一次創(chuàng)建在 <字符常量緩沖區(qū)(Data Segment)> 中
// 下次再發(fā)現(xiàn)調(diào)用 "value" , 直接去 Data Segment 中拿值 , 不再新建
// 3 6:invokespecial #19 <Method void String(String)>
// 4 9:astore_1
// 5 10:return
// 至此共創(chuàng)建了兩個(gè)對(duì)象
}
public void methodManyString() {
String manyObject = "";
// 0 0:ldc1 #25 <String "">
// 1 2:astore_1
for(int index = 0; index < 10; index++)
//* 2 3:iconst_0
//* 3 4:istore_2
//* 4 5:goto 31
manyObject = (new StringBuilder(String.valueOf(manyObject))).append("line").toString();
// 5 8:new #27 <Class StringBuilder> 在 循環(huán)體內(nèi) 創(chuàng)建StringBuilder對(duì)象
// 雖然代碼為 String += "line" ; 但編譯器實(shí)際創(chuàng)建的還是StringBuilder對(duì)象來處理字符串
// 注意 JDK1.4 版本以前,編譯器 實(shí)際調(diào)用的是StringBuffer, 直到 JDK1.5以后,底層用StringBuilder代替
// 6 11:dup
// 7 12:aload_1
// 8 13:invokestatic #29 <Method String String.valueOf(Object)>
// 9 16:invokespecial #33 <Method void StringBuilder(String)>
// 10 19:ldc1 #34 <String "line">
// 如果 <字符常量緩沖區(qū)(Data Segment)> 沒有 "line" 的串對(duì)象,則創(chuàng)建了一個(gè)對(duì)象,以后每循環(huán)一次重復(fù)使用,不再新建
// 11 21:invokevirtual #36 <Method StringBuilder StringBuilder.append(String)>
// 12 24:invokevirtual #40 <Method String StringBuilder.toString()>
// 13 27:astore_1
// 14 28:iinc 2 1
// 15 31:iload_2
// 16 32:bipush 10
// 17 34:icmplt 8
// 18 37:return
// 至此,使用 String string += "line" ; 在循環(huán)體中,循環(huán)多少次,就創(chuàng)建多少個(gè)全新的StringBuilder對(duì)象
}
public void methodStringBuffer() {
StringBuffer stringBuffer = new StringBuffer();
// 0 0:new #48 <Class StringBuffer> 新建 StringBuffer 對(duì)象
// 1 3:dup
// 2 4:invokespecial #50 <Method void StringBuffer()>
// 3 7:astore_1
for(int index = 0; index < 10; index++)
//* 4 8:iconst_0
//* 5 9:istore_2
//* 6 10:goto 23
stringBuffer.append("line"); // 只是調(diào)用 StringBuffer 的 append 方法 壘加 字符串 并未創(chuàng)建新對(duì)象
// 7 13:aload_1
// 8 14:ldc1 #34 <String "line">
// 如果 <字符常量緩沖區(qū)(Data Segment)> 沒有 "line" 的串對(duì)象,則創(chuàng)建了一個(gè)對(duì)象,以后每循環(huán)一次重復(fù)使用,不再新建
// 9 16:invokevirtual #51 <Method StringBuffer StringBuffer.append(String)>
// 10 19:pop
// 11 20:iinc 2 1
// 12 23:iload_2
// 13 24:bipush 10
// 14 26:icmplt 13
// 15 29:return
// 至次,只創(chuàng)建了一個(gè)StringBuffer對(duì)象
}
public void methodStringBuilder() {
StringBuilder stringBuilder = new StringBuilder();
// 0 0:new #27 <Class StringBuilder> 新建 StringBuilder 對(duì)象
// 1 3:dup
// 2 4:invokespecial #57 <Method void StringBuilder()>
// 3 7:astore_1
for(int index = 0; index < 10; index++)
//* 4 8:iconst_0
//* 5 9:istore_2
//* 6 10:goto 23
stringBuilder.append("line"); // 只是調(diào)用 StringBuilder 的 append 方法 壘加 字符串 并未創(chuàng)建新對(duì)象
// 7 13:aload_1
// 8 14:ldc1 #34 <String "line">
// 如果 <字符常量緩沖區(qū)(Data Segment)> 沒有 "line" 的串對(duì)象,則創(chuàng)建了一個(gè)對(duì)象,以后每循環(huán)一次重復(fù)使用,不再新建
// 9 16:invokevirtual #36 <Method StringBuilder StringBuilder.append(String)>
// 10 19:pop
// 11 20:iinc 2 1
// 12 23:iload_2
// 13 24:bipush 10
// 14 26:icmplt 13
// 15 29:return
// 至次,只創(chuàng)建了一個(gè)StringBuilder對(duì)象
}
}
posted on 2014-05-13 16:52 00001000 閱讀(214) 評(píng)論(0) 編輯 收藏 所屬分類: Java 語言基礎(chǔ)