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

vij*_*shi 4 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
Run Code Online (Sandbox Code Playgroud)

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

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

T.J*_*der 10

当你有这个:

String s1 = "Hello".concat("World");
String s2 = s1.intern();
System.out.println(s1 == s2); //true
Run Code Online (Sandbox Code Playgroud)

... 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
Run Code Online (Sandbox Code Playgroud)

... 在代码运行之前池中已经有一个"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
Run Code Online (Sandbox Code Playgroud)

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

根据我的理解,s1将在常量池中创建"HelloWorld"

不,concat不将其返回字符串放入池中.s1只是把在游泳池后,当你调用s1.intern(),且仅当有尚未在游泳池等效字符串.当代码中没有"Line-2"时,没有,但代码中有"Line-2":该"HelloWorld"行上的文字.

  • @vijayjoshi:`intern`不一定返回你调用它的字符串对象.事实上,这是"实习生"目的的一部分.如果在字符串对象上调用`intern`,该字符串对象与池中已有的不同字符串对象具有相同的字符,则`intern`将从池中返回该对象.但是如果你在一个字符串对象上调用`intern`,*它不具有与池中已有的任何对象相同的字符,`intern`会将它添加到池中并返回相同的对象.在你的例子中,"Line-2"被注释掉了,`s1.intern()`添加它......*(续)* (2认同)