我理解String equals()方法是如何工作的,但我对String ==运算符的一些结果感到惊讶。
我希望==比较引用,就像对其他对象一样。
然而,不同的String对象(具有相同的内容)==返回true,甚至对于静态字符串对象(具有相同的内容),这显然不是相同的内存地址。
我猜= =已被定义为与equals相同以防止其滥用
答案 0 :(得分:12)
不,==
只是比较引用。但是,我怀疑你被编译时常量被囚禁 - 所以两个文字最终会引用同一个字符串对象。例如:
String x = "xyz";
String y = "xyz";
System.out.println(x == y); // Guaranteed to print true
StringBuilder builder = new StringBuilder();
String z = builder.append("x").append("yz").toString();
System.out.printn(x == z); // Will print false
来自section 3.10.5 of the Java language specification:
字符串文字 - 或者更常见的是,作为常量表达式(第15.28节)的值的字符串 - 是“interned”,以便使用String.intern方法共享唯一的实例。
答案 1 :(得分:5)
返回相同的原因是因为内存优化(并不总是保证会发生)具有相同内容的字符串将指向相同的内存区域以节省空间。在静态对象的情况下,它们总是指向同一个东西(因为static关键字只有一个)。再次不要依赖上面的内容而是使用Equals()代替。
我应该从Jon Skeet中指出的一点是,它始终保证编译时常量。但是再次使用equals()会更清楚地阅读。
答案 2 :(得分:4)
答案 3 :(得分:3)
== 运算符始终会比较 Java 中的引用,而不会比较内容。可能发生的情况是,一旦声明了字符串文字,就会将此对象发送到JVM的字符串池,如果重复使用相同的文字,则会将相同的对象放在那里。可以在以下代码段中看到对此行为的简单测试:
String a = "a string";
String b = "a string";
System.out.println( a == b ); // will print true
String c = "other string";
String d = new String( "other string" );
System.out.println( c == d ); // will print false
第二种情况打印为false,因为变量 d 是使用直接创建的String对象初始化的,而不是文字,因此它不会转到字符串池。
字符串池不是java规范的一部分,并且不建议信任它的行为。您应该始终使用equals来比较对象。
答案 4 :(得分:0)
我猜= =已被定义为与equals相同以防止其滥用
错误。这里发生的是当编译器发现你在两个不同的地方使用相同的字符串时,它只将它存储在程序的数据部分中一次。读入一个字符串或从较小的字符串创建它,然后比较它们。
编辑:请注意,当我说上面的“相同字符串”时,我只是指编译器在运行时知道的字符串文字。