有如下代码:
String s = new String("1");
s.intern();
String s2 = "1";
System.out.println(s == s2);
String s3 = new String("1")+new String("1");
s3.intern();
String s4 = "11";
System.out.println(s3 == s4);
上面代码的输出是:
false
true
我知道 s
和 s2
是不同的对象,所以结果计算为 false,但第二个结果计算为 true。谁能告诉我区别?
最佳答案
这是发生了什么:
例子1
String s1 = new String("1");
s1.intern();
String s2 = "1";
- 字符串文字
"1"
(传递到String
构造函数中)驻留在地址 A。
字符串s1
在地址 B 创建,因为它不是文字或常量表达式。 - 调用
intern()
无效。字符串"1"
已经被驻留,运算结果没有赋值回s1
。 - 从字符串池中检索到值为
"1"
的字符串s2
,因此指向地址 A。
结果:字符串 s1
和 s2
指向不同地址。
例子2
String s3 = new String("1") + new String("1");
s3.intern();
String s4 = "11";
- 字符串
s3
在地址 C 处创建。 - 调用
intern()
将地址 C 中值为"11"
的字符串添加到字符串池中。 - 字符串
s4
的值为"11"
是从字符串池中检索到的,因此指向地址 C。
结果:字符串 s3
和 s4
指向相同地址。
总结
String "1"
在调用 intern()
之前被驻留,因为它存在于 s1 = new String("1 ")
构造函数调用。
将构造函数调用更改为 s1 = new String(new char[]{'1'})
将使 s1 == s2
的比较结果为真,因为两者现在都将引用通过调用 s1.intern()
显式保留的字符串。
(我使用了 this answer 中的代码来获取有关字符串内存位置的信息。)
关于java - Java 中字符串实习的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42824821/