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

时间:2018-01-07 17:03:59

标签: java string string-pool

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仍然是假的吗?

1 个答案:

答案 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"字面值。