4
String s1 = "Hello".concat("World");
String s3 = new String("HelloWorld"); //Line-2
String s2 = s1.intern();
System.out.println(s1 == s2); //false
System.out.println(s1 == s3); //false
System.out.println(s2 == s3); //false

如果我删除第 2 行并比较 s1==s2,它将返回 true。谁能解释一下 Line-2 之后字符串池中到底发生了什么?堆和常量池中的每一行发生了什么?

据我了解,s1 将在常量池中创建“HelloWorld”。但仍然 s1 == s2 是假的?

4

1 回答 1

10

当你有这个:

String s1 = "Hello".concat("World");
String s2 = s1.intern();
System.out.println(s1 == s2); //true

...s1.intern()添加s1到池中并返回s1,因为池中已经没有等效的字符串。所以自然s1 == s2是真的。

但是当你有这个时:

String s1 = "Hello".concat("World");
String s3 = new String("HelloWorld"); //Line-2
String s2 = s1.intern();
System.out.println(s1 == s2); //false
System.out.println(s1 == s3); //false
System.out.println(s2 == s3); //false

...在代码运行之前,池中已经有一个"HelloWorld"字符串(因为在类加载期间将字符串文字放入池中)。所以调用s1.intern()从池中返回字符串,而不是s1. 也是s1 == s2假的。

如果我们这样做,这一点会更加明显:

String s1 = "Hello".concat("World");
String sx = "HelloWorld";
String s3 = new String(sx);
String s2 = s1.intern();
System.out.println(s1 == s2); //false
System.out.println(s1 == s3); //false
System.out.println(s2 == s3); //false
System.out.println(s1 == sx); //false
System.out.println(s2 == sx); //true

sx是代码开始运行之前池中的那个。

据我了解,s1 将在常量池中创建“HelloWorld”

不,concat不会将其返回字符串放入池中。s1仅当您调用时s1.intern()并且仅当池中还没有等效字符串时才将其放入池中。代码中没有“Line-2”,但代码中有“Line-2”:该"HelloWorld"行的文字。

于 2018-01-07T17:06:55.583 回答