面試題
該程序的輸出結(jié)果?
正確結(jié)果是:
true
false
結(jié)果分析
對于String s1="a"+"bc",在編譯期會優(yōu)化成String s1="abc",生成的字節(jié)碼看不到"a"和"bc";對于s2也會做同樣的優(yōu)化處理:String s2="abc"。s1和s2都指向常量池中的"abc",故s1==s2結(jié)果返回true。這種編譯期的優(yōu)化技術(shù)叫做常量折疊,其發(fā)生的條件是:必須是編譯期常量之間進行運算才會進行常量折疊。編譯期常量(編譯的時候就可以確定其值的常量)有:
- 字面量:數(shù)字字面量,字符串字面量等
- 編譯期常量進行簡單運算的結(jié)果:1+2,"a"+"b"等
- 被編譯器常量賦值的final的基本類型和字符串變量等
s3是兩個非final的變量相加,不會發(fā)生常量折疊,而是根據(jù) String 類特有的 + 運算符重載,變成類似這樣的代碼(jdk1.8.0_111,不同版本可能生成的字節(jié)碼結(jié)果不一樣):
String s3 = new StringBuilder(a).Append(bc).toString();
toString方法(源碼如下圖所示)會new一個新的String變量出來,使得s1==s3結(jié)果為false(如果對String a和String bc都使用final修飾,那么s1==s3的結(jié)果會因常量折疊而為true)。
為了更清晰的明白整個過程這里對題中字節(jié)碼進行進行反編譯,題中代碼等價于:
字節(jié)碼內(nèi)容如下圖所示:
JAVA修身之路,專注java學習和分享,不止java。