一、String str = new String(“ab”) 會(huì)創(chuàng)建幾個(gè)對(duì)象?
public class StringNewTest {
public static void main(String[] args) {
String str = new String("ab");
}
}
javap -v StringNewTest.class
反編譯后僻弹, 部分片段如下:
根據(jù)反編譯后字節(jié)碼分析:
- 一個(gè)對(duì)象是:new 關(guān)鍵字在堆空間創(chuàng)建的臭家;
- 另一個(gè)對(duì)象是:字符串常量池中的對(duì)象 "ab"。 (如果前后文中還有代碼鞠值,并且已經(jīng)有 ab 常量在常量池存在時(shí),ab 將不再創(chuàng)建渗钉,因?yàn)樵诔A砍刂荒艽嬖谝环菹嗤膶?duì)象)
結(jié)論是 2 個(gè)對(duì)象彤恶。
二、String str = new String(“a”) + new String(“b”) 會(huì)創(chuàng)建幾個(gè)對(duì)象 ?
public class StringNewTest {
public static void main(String[] args) {
String str = new String("a") + new String("b");
}
}
javap -v StringNewTest.class
反編譯后鳄橘, 部分片段如下:
根據(jù)反編譯后字節(jié)碼分析:
- 對(duì)象1: new StringBuilder()
- 對(duì)象2: new String(“a”)
- 對(duì)象3: 常量池中的"a"
- 對(duì)象4: new String(“b”)
- 對(duì)象5: 常量池中的"b"
深入剖析: StringBuilder 的 toString() 方法中有 new String(value, 0, count) 声离,
- 對(duì)象6 :new String(“ab”)
StringBuilder 的 toString() 的調(diào)用,在字符串常量池中瘫怜,沒有生成 "ab"术徊。
如果前后文中還有代碼,并且已經(jīng)常量在常量池存在時(shí)鲸湃,相同的常量 將不再創(chuàng)建赠涮,因?yàn)樵诔A砍刂荒艽嬖谝环菹嗤膶?duì)象子寓。
結(jié)論是 6 個(gè)對(duì)象。
三笋除、String str =“a”+ “b” 會(huì)創(chuàng)建幾個(gè)對(duì)象 ?
public class StringNewTest {
public static void main(String[] args) {
String str = "a" + "b";
}
}
javap -v StringNewTest.class
反編譯后别瞭, 部分片段如下:
"a" + "b"
在編譯時(shí),就已經(jīng)編譯為ab
株憾, 被放到常量池中蝙寨。
所以只有一個(gè)對(duì)象 :ab
如果前后文中還有代碼,并且已經(jīng)有 ab 常量在常量池存在時(shí)嗤瞎,ab 將不再創(chuàng)建墙歪,因?yàn)樵诔A砍刂荒艽嬖谝环菹嗤膶?duì)象。
字符串拼接操作的總結(jié)
- 常量 與 常量 的拼接結(jié)果在 常量池贝奇,原理是 編譯期 優(yōu)化虹菲;
- 常量池 中不會(huì)存在相同內(nèi)容的常量;
- 只要其中一個(gè)是變量掉瞳,結(jié)果在堆中毕源。 如:
String s2 = s1+"DEF"
;
變量拼接的原理 是StringBuilder 。 - 如果拼接的結(jié)果是調(diào)用
intern()
方法陕习,則主動(dòng)將常量池中 還沒有的字符串 對(duì)象放入池中霎褐,并返回地址。
參考:https://blog.csdn.net/xiaojin21cen/article/details/106404531