3 回答

TA貢獻(xiàn)1876條經(jīng)驗(yàn) 獲得超6個(gè)贊
先說(shuō)一下我的答案: 我感覺(jué)是 3 個(gè).
首先, 明確一下 創(chuàng)建對(duì)象
的具體含義. 按我的理解, 如果字符串是 字符常量
, 那么這個(gè)字符串對(duì)象是在編譯時(shí)候確定好的, 它是存放在常量池中的, 因此就不算是創(chuàng)建了一個(gè)字符串對(duì)象, 而如果有 String b = new String("abc")
之類(lèi)的操作, 那么可以認(rèn)為是創(chuàng)建了字符串對(duì)象, 并與變量 b
關(guān)聯(lián).
根據(jù)上面的定義, 那么有: "a", "b", "abc", "567" 都是常量, 放在常量池中的, 因此就不算是創(chuàng)建對(duì)象了.
那么來(lái)看一下代碼:
源碼:
1: String a,b,c;
2: a = "a";
3: b = "b";
4: a = a+b;
5: StringBuffer d = new StringBuffer("abc");
6: d = d.append("567");
為了方便起見(jiàn), 我手動(dòng)給每一行編號(hào)了.
再來(lái)看一下對(duì)應(yīng)的字節(jié)碼:
Code:
stack=3, locals=5, args_size=1
0: ldc #2 // String a
2: astore_1
3: ldc #3 // String b
5: astore_2
6: new #4 // class java/lang/StringBuilder
9: dup
10: invokespecial #5 // Method java/lang/StringBuilder."<init>":()V
13: aload_1
14: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
17: aload_2
18: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
21: invokevirtual #7 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
24: astore_1
25: new #8 // class java/lang/StringBuffer
28: dup
29: ldc #9 // String abc
31: invokespecial #10 // Method java/lang/StringBuffer."<init>":(Ljava/lang/String;)V
34: astore 4
36: aload 4
38: ldc #11 // String 567
40: invokevirtual #12 // Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;
43: astore 4
45: return
由字節(jié)碼可以看出, 源碼的第四行 a = a+b
翻譯為如下代碼:
StringBuilder builder = new StringBuilder();
builder.append(a);
builder.append(b);
a = builder.toString();
那么這里就新建了一個(gè)對(duì)象 new StringBuilder()
, 接著調(diào)用 builder.toString()
方法, 它源碼如下:
@Override
public String toString() {
// Create a copy, don't share the array
return new String(value, 0, count);
}
于是 builder.toString()
方法創(chuàng)建了一個(gè) String 對(duì)象, 因此目前我們已經(jīng)創(chuàng)建了 兩個(gè)對(duì)象
了.
接著第五行 StringBuffer d = new StringBuffer("abc")
毫無(wú)疑問(wèn)是 創(chuàng)建了對(duì)象 StringBuffer
, 于是我們就有 三個(gè)對(duì)象
了. 有一點(diǎn)需要注意的是 StringBuffer d
從始至終都沒(méi)有調(diào)用 toString
方法, 因此就不會(huì)有多余的 String 創(chuàng)建出來(lái).
總結(jié):
"a": 字符串常量, 不算創(chuàng)建對(duì)象
"b": 字符串常量, 不算創(chuàng)建對(duì)象
builder 對(duì)象: 在執(zhí)行
a = a+b
時(shí)創(chuàng)建."ab": 由
StringBuilder.toString()
創(chuàng)建."abc": 字符串常量, 不算創(chuàng)建對(duì)象
"567": 字符串常量, 不算創(chuàng)建對(duì)象
d: 通過(guò)
new StringBuffer("abc")
創(chuàng)建.
因此最終有三個(gè)對(duì)象創(chuàng)建了.
添加回答
舉報(bào)