有一道這樣的程序:
1 public class TestStringDemo { 2 3 public static void main(String[] args) { 4 5 String s1 = "Programming"; 6 String s2 = new String("Programming"); 7 String s3 = "Program"; 8 String s4 = "ming"; 9 String s5 = "Program" + "ming"; 10 String s6 = s3 + s4; 11 System.out.println(s1 == s2); 12 System.out.println(s1 == s5); 13 System.out.println(s1 == s6);
17 } 18 }
讓自己跟着做一遍,加深印象.....
程序的輸出:
false true false
第一個輸出:false ,我們還可以理解;
第二輸出:true,跟我們的結果不一樣,為什么輸出true,不是說好了嗎?字符串的+操作其本質是new了StringBuilder對象進行append操作,拼接后調用toString()返回String對象?
我們可以用以下命令獲得.class文件對應的JVM字節碼指令
javap -c StringEqualTest.class
JVM字節碼指令:
第20~22行,我們通過對比知道,String s5 = "Program" + "ming";在被編譯器優化成了String s5 = "Programming";
也可以得出字符串常量相加,不會用到StringBuilder對象,有一點要注意的是:字符串常量和字符串是不同的概念,字符串常量儲存於方法區,而字符串儲存於堆(heap)。
第三個輸出:false ;通過以上的分析,自然也就明白了為森馬是false了
我們來分析一下JVM字節碼指令
- 第24行:使用new 了 StringBuider對象
- 第25行:進行StringBuider對象初始化
- 第26行:使用append() 方法拼接s3的內容
- 第27行:再使用append() 方法拼接s4的內容
- 第28行:最后調用toString() 返回String對象
總結:
- 兩個或者兩個以上的字符串常量相加,在預編譯的時候“+”會被優化,相當於把兩個或者兩個以上字符串常量自動合成一個字符串常量
- 字符串的+操作其本質是new了StringBuilder對象進行append操作,拼接后調用toString()返回String對象