字符串池与concat一起使用时的行为有所不同?

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 

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

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

当你有这个:

 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.intern()s1仅在稍后放入池中,并且仅当池中没有等效字符串时才会放入池中。 当你在代码中没有“Line-2”时就没有了,但是当代码中有“Line-2”时:该行上的"HelloWorld"文字。