public class Test {
public static void main(String[] args)
{
String s1 = "HELLO";
String s2 = "HELLO";
System.out.println(s1 == s2); // true
}
}
但是当我使用:
public class Test {
public static void main(String[] args)
{
String s1 = new String("HELLO");
String s2 = new String("HELLO");
System.out.println(s1 == s2); // false
}
}
有人可以在这里解释其中的区别吗?谢谢!
对于String文字,在String Object Pool中创建新的Object之前,JVM将检查SCP区域中是否已存在相同的Object,否则,它将指向同一对象而不是创建新的Object。因此,在代码s1下面== s2是true
String s1 = "HELLO";
String s2 = "HELLO";
System.out.println(s1 == s2); // true
但是我们正在使用new关键字创建新对象,它将在堆区域中创建,因此s1和s2指向两个不同的对象,因此返回false
在第一个示例中
String s1 = "HELLO";
String s2 = "HELLO";
s1
和s2
的值是编译时常量。因此,编译器仅生成单个String
对象,并保留值"HELLO"
并将其赋值给s1
和s2
。这是众所周知的编译器优化Common Subexpression Elimination的特例。因此,s1 == s2
返回true
。
在第二个示例中,通过String
显式构造了两个不同的new
。因此,根据new
的语义,它们必须是单独的对象。
我创建了Ideone demo一会儿,突出显示了某些表现出这种行为的情况。
您可以使用String
强制返回相同的String::intern()
:
String::intern()
String s1 = new String("HELLO").intern(); String s2 = new String("HELLO").intern(); System.out.println(s1 == s2); // will print "true";
==测试引用是否相等(它们是否是同一对象)。
==比较对象引用指针。当2个对象是完全相同的对象时,它将为true。
==测试引用是否相等(它们是否是同一对象)。
i第一种情况u比较两个字符串及其ASCII值。那就是为什么... // true在第二种情况下,您正在比较两个函数/方法。那就是为什么... // false
第一个是正确的,因为s1和s2在方法区域中引用相同的字符串文字,而内存引用是相同的。 (==仅检查字符串中的引用)。当多次创建同一字符串文字时,每个唯一的字符串值仅存储一个副本。第二个是假的,因为s1和s2引用堆中的两个不同的对象。不同的对象始终具有不同的内存引用。