String

String “abc” 和 new String("abc") 相等吗?

https://mp.weixin.qq.com/s/95GfiYD0E_wRovOojVGP4Q

"abc" 与 "abc"

String st1 = "abc";
String st2 = "abc";
System.out.println(st1 == st2); // true
System.out.println(st1.equals(st2)); // true

常量池里的同一个对象

"abc" 与new String("abc")

 String st1 = new String("abc");
 String st2 = "abc";
 System.out.println(st1 == st2); // false
 System.out.println(st1.equals(st2)); // true

String st1 = new String(“abc”);在内存中创建了两个对象,一个在[堆内存]#),一个在常量池,堆内存对象是常量池对象的一个拷贝副本。

"abc" 与 "a" + "b" + "c"

 String st1 = "a" + "b" + "c";
 String st2 = "abc";
 System.out.println(st1 == st2); // true
 System.out.println(st1.equals(st2)); // true

“a”,”b”,”c”三个本来就是字符串常量,进行+符号拼接之后变成了“abc”,“abc”本身就是字符串常量(Java中有常量优化机制),所以常量池立马会创建一个“abc”的字符串常量对象,在进行st2=”abc”,这个时候,常量池存在“abc”,所以不再创建。所以,不管比较内存地址还是比较字符串序列,都相等。

"abc" 与 st1 + "c"

这个拼接的原理是由StringBuilder或者StringBuffer类和里面的append方法实现拼接,然后调用 toString() 把拼接的对象转换成字符串对象,最后把得到字符串对象的地址赋值给变量。

大致内存过程

1)常量池创建“ab”对象,并赋值给st1,所以st1指向了“ab”

2)常量池创建“abc”对象,并赋值给st2,所以st2指向了“abc”

3)由于这里走的+的拼接方法,所以第三步是使用StringBuffer类的append方法,得到了“abc”,这个时候内存0x0011表示的是一个StringBuffer对象,注意不是String对象。

4)调用了Object的toString方法把StringBuffer对象装换成了String对象。

5)把String对象(0x0022)赋值给st3

所以,st3和st2进行==判断结果是不相等,因为两个对象内存地址不同。

String `+` 拼接怎么实现的

StringBuilder vs String concatenation in toString() in Java

15.18.1. String Concatenation Operator +

Last updated

Was this helpful?