我正在尝试理解Java的String
课程,但我很难理解下面描述的情况。
请考虑以下示例代码段:
String x = new String("Hey");
String y = "Hey";
如果我使用bool = y == x.intern();
,则变量bool
将等于 true
。
我的问题是:
当我做出这样的声明时:
String b = "h";
String a = b.intern + "ey";
boolean x = a == "hey";
x
的值为 false
,但当我a = (b + "ey").intern();
x
的值为 {{1 }}
为什么在第二个示例中不会true
?是否因为第一个示例中的声明不相同?如果是,有什么区别?
答案 0 :(得分:5)
用你的第一个例子:
String y = "Hey";
Java会自动插入字符串文字,例如this(JLS section 3.10.5):
此外,字符串文字总是指同一个类的实例 串。这是因为字符串文字 - 或者更一般地说是字符串 这是常量表达式的值(§15.28) - 是“实习” 以便使用String.intern。方法共享唯一的实例。
因此,当您致电x.intern()
时,您会获得"Hey"
的实习副本,因此它们是同一个对象,而==
会返回true
。
但是在第二个例子中,b.intern()
是一个在运行时计算的方法调用,Java的连接运算符将返回一个新的String
(非实习),这是一个与字符串不同的对象文字"hey"
(已经实习),所以==
会返回false
(不同的对象)。
编辑
要清除字符串连接发生的情况,请转到JLS Section 15.18.1:
字符串连接的结果是对String对象的引用 这是两个操作数字符串的串联。那些角色 左手操作数的前面是右手的字符 新创建的字符串中的操作数。
除非表达式是a,否则新创建String对象(第12.5节) 编译时常量表达式(§15.28)。
但是,b.intern() + "ey";
不是编译时常量表达式,因此生成的String
对象尚未被实现,==
将检测到它是与实习"hey"
不同的对象。
答案 1 :(得分:3)
这个创建一个字符串并存储它:
String a = b.intern() + "ey";
这个创建一个字符串,实习并存储实习版本:
String a = (b + "ey").intern();
所有具有相同内容的实习字符串均为==
所有字符串文字(以“hey”形式提供的字符串)都由内部编译器实现。
未实习但具有相同内容的字符串仅为equal()
而非==
对于后代,还有一个......编译器优化了+
导致“嘿”并实习实验就像字符串文字“嘿”一样
String a = "h" + "ey";
答案 2 :(得分:0)
Java使用StringBuilder
连接String
:
b.intern() + "ey"
变成类似于new StringBuilder(b.intern()).append("ey").toString()
的东西。这会创建一个新的String
,因此它不会==
到"hey"
。