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仍然是假的吗?
答案 0 :(得分: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"
字面值。