有一道这样的程序:
public class TestStringDemo { public static void main(String[] args) { String s1 = "Programming"; String s2 = new String("Programming"); String s3 = "Program"; String s4 = "ming"; String s5 = "Program" + "ming"; String s6 = s3 + s4; System.out.println(s1 == s2); System.out.println(s1 == s5); System.out.println(s1 == } }
让自己跟着做一遍,加深印象.....
程序的输出:
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对象