使用字面量创建字符串常量
每当我们使用字面量创建字符串常量时(比如:String s = "a"),JVM会首先检查字符串常量池,如果该字符串已经存在常量池中,那么就将此字符串对象的地址赋值给引用s(引用s在Java栈中)。如果字符串不存在常量池中,就会实例化该字符串并且将其放到常量池中,并将此字符串对象的地址赋值给引用s(引用s在Java栈中)。
因此以上代码结果为true。
使用new关键字创建String对象
每当我们使用关键字new(String s=new String(”a”);)创建字符串常量时,JVM会首先检查字符串常量池,如果该字符串已经存在常量池中,那么不再在字符串常量池创建该字符串对象,而直接堆中复制该对象的副本,然后将堆中对象的地址赋值给引用s,如果字符串不存在常量池中,就会实例化该字符串并且将其放到常量池中,然后在堆中复制该对象的副本,然后将堆中对象的地址赋值给引用s。
因此以上代码结果为false,false。
从上面的示意图可以看出,s1,s2,s3分别引用了三个不同的对象。
那么根据以上两个例子,String s = "a"+"b"+"c"按道理应该会创建"a","b","c","abc"四个对象,但Java在编译是时进行了优化,"a"+"b"+"c"会直接被拼接成"abc",所以String s = "a"+"b"+"c",实际上就等同于String s = "abc",也就是说只会在字符串常量池创建"abc"一个对象。