Java中字符串相加和字符串常量相加区别

时间:2021-09-30 12:48:23

有一道这样的程序:

 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字节码指令:

Java中字符串相加和字符串常量相加区别

第20~22行,我们通过对比知道,String s5 = "Program" + "ming";在被编译器优化成了String s5 = "Programming";

也可以得出字符串常量相加,不会用到StringBuilder对象,有一点要注意的是:字符串常量和字符串是不同的概念,字符串常量储存于方法区,而字符串储存于堆(heap)。

第三个输出:false ;通过以上的分析,自然也就明白了为森马是false了

我们来分析一下JVM字节码指令

Java中字符串相加和字符串常量相加区别

  1. 第24行:使用new 了 StringBuider对象
  2. 第25行:进行StringBuider对象初始化
  3. 第26行:使用append() 方法拼接s3的内容
  4. 第27行:再使用append() 方法拼接s4的内容
  5. 第28行:最后调用toString() 返回String对象

总结:

  • 两个或者两个以上的字符串常量相加,在预编译的时候“+”会被优化,相当于把两个或者两个以上字符串常量自动合成一个字符串常量
  • 字符串的+操作其本质是new了StringBuilder对象进行append操作,拼接后调用toString()返回String对象