public class Comparison {
public static void main(String[] args) {
String s = "prova";
String s2 = "prova";
System.out.println(s == s2);
System.out.println(s.equals(s2));
}
}
输出:
true
true
在我的机器上。为什么?不应该==比较对象引用是否相等?
答案 0 :(得分:32)
因为 String
实例是不可变的,所以Java语言能够对String
文字进行一些优化(或更一般地,{{其值为编译时常量的<}> interned 并实际引用相同的(即String
)对象。
JLS 3.10.5 String Literals
每个字符串文字都是对
==
实例的引用。class String
个对象具有常量值。字符串文字 - 或者更一般地说,是作为常量表达式值的字符串 - 使用String.intern
方法“实现”以便共享唯一实例。
这就是您获得以下内容的原因:
String
这就是说,你需要 NOT 依靠System.out.println("yes" == "yes"); // true
System.out.println(99 + "bottles" == "99bottles"); // true
System.out.println("7" + "11" == "" + '7' + '1' + (char) (50-1)); // true
System.out.println("trueLove" == (true + "Love")); // true
System.out.println("MGD64" == "MGD" + Long.SIZE);
进行==
比较,并且应该String
用于非{ {1}} equals
。特别是,不要只想null
instanceof String
所有intern()
,以便在不知道字符串实习如何工作的情况下使用String
。
==
如果出于某些特殊原因,您需要创建两个 new String(...)
对象(因此根据定义不是String
),而是==
,然后你可以使用这个构造函数:
public String(String original)
:初始化一个新创建的equals
对象,使其表示与参数相同的字符序列;换句话说,新创建的字符串是参数字符串的副本。 除非需要显式的原始副本,否则不必使用此构造函数,因为String
是不可变的。
因此,您可以:
Strings
System.out.println("x" == new String("x")); // false
运算符始终创建一个新对象,因此上述内容可以保证打印new
。也就是说,这通常不是你真正需要做的事情。只要有可能,您应该只使用字符串文字,而不是为它显式创建false
。
答案 1 :(得分:11)
JLS, 3.10.5 =&gt;保证文本字符串对象将被同一虚拟机中运行的任何其他代码重用,恰好包含相同的字符串文字
答案 2 :(得分:5)
如果显式创建新对象,==
将返回false:
String s1 = new String("prova");
String s2 = new String("prova");
System.out.println(s1 == s2); // returns false.
否则JVM可以使用相同的对象,因此s1 == s2将返回true。
答案 3 :(得分:2)
确实如此。但是字符串文字是合并的,因此"prova"
返回相同的实例。
答案 4 :(得分:2)
String s = "prova";
String s2 = "prova";
s
和s2
是文字字符串,它们指向JVM字符串池中的同一对象,因此比较返回true。
答案 5 :(得分:1)
是的,“prova”存储在java内部字符串池中,因此它的引用相同。
答案 6 :(得分:1)
源代码文字是constant pool的一部分,因此如果同一个文字出现多次,它将在运行时成为同一个对象。
答案 7 :(得分:1)
JVM可以优化String的使用,以便内存中只有一个“相等”字符串的实例。在这种情况下,==运算符也将返回true。但不要指望它。
答案 8 :(得分:0)
您必须明白“==”比较引用,“等于”比较值。 s
和s1
都指向相同的字符串文字,因此它们的引用是相同的。
答案 9 :(得分:0)
当您在java代码中放入文字字符串时,编译器会自动 interned 字符串,即创建一个静态全局实例。或者更具体地说,它被放入一个实习字符串表中。内容方面完全相同的任何其他引用字符串将引用相同的实习字符串。
因此,在您的代码中,s2 是相同的字符串
答案 10 :(得分:0)
理想情况下,它不应该永远发生。因为java规范保证这一点。所以我认为它可能是JVM中的错误,你应该向sun microsystems报告。