爲了找出答案,我寫了一個類像下面這樣:
class Test {
String a = "abc" ;
StringBuilder buffer = new StringBuilder() ;
public void normal() {
buffer.append("abc") ;
buffer.append("abc") ;
}
public void clever() {
buffer.append(a) ;
buffer.append(a) ;
}
}
如果我們編譯這個,然後運行javap的在它提取字節碼:
14:09:58 :: javap $ javap -c Test
Compiled from "Test.java"
class Test extends java.lang.Object{
java.lang.String a;
java.lang.StringBuilder buffer;
Test();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: aload_0
5: ldC#2; //String abc
7: putfield #3; //Field a:Ljava/lang/String;
10: aload_0
11: new #4; //class java/lang/StringBuilder
14: dup
15: invokespecial #5; //Method java/lang/StringBuilder."<init>":()V
18: putfield #6; //Field buffer:Ljava/lang/StringBuilder;
21: return
public void normal();
Code:
0: aload_0
1: getfield #6; //Field buffer:Ljava/lang/StringBuilder;
4: ldC#2; //String abc
6: invokevirtual #7; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
9: pop
10: aload_0
11: getfield #6; //Field buffer:Ljava/lang/StringBuilder;
14: ldC#2; //String abc
16: invokevirtual #7; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
19: pop
20: return
public void clever();
Code:
0: aload_0
1: getfield #6; //Field buffer:Ljava/lang/StringBuilder;
4: aload_0
5: getfield #3; //Field a:Ljava/lang/String;
8: invokevirtual #7; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
11: pop
12: aload_0
13: getfield #6; //Field buffer:Ljava/lang/StringBuilder;
16: aload_0
17: getfield #3; //Field a:Ljava/lang/String;
20: invokevirtual #7; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
23: pop
24: return
}
我們可以看到2件事。
首先,normal
方法是使用相同的字符串實例爲這兩個呼叫的(事實上,它是相同的文字作爲被設置爲在初始化塊中的這個類的a
成員變量)
其次, clever
方法比normal
更長。這是因爲需要額外的步驟才能將該屬性從類中取出。因此,故事的寓意是,99%的時間,Java在自己的事情上以正確的方式做事,而且不需要嘗試聰明;-)(和javap是一個非常酷的工具,當時你想知道到底發生了什麼)
javap,而不是jsonp。 – danben 2010-06-15 13:27:56
哎呀! ;-)你能說出我*應該做的事嗎? ;-) – 2010-06-15 13:36:19
如果比較代碼長度,你應該使用局部變量而不是'clever'中的字段;但無論如何,這個問題主要是關於創建字符串的問題,並且從您的示例中可以看出,只涉及一個String對象! – 2010-06-15 13:37:15