字符串池与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"
文字。