基本Java问题:字符串相等

时间:2009-12-13 10:49:00

标签: java string equality

public class A {

    static String s1 = "I am A";

    public static void main(String[] args) {
        String s2 = "I am A";
        System.out.println(s1 == s2);
    }
}

以上程序输出“true”。两者是两个不同的标识符/对象输出是如何“真”?

我的理解是JVM会为每个对象创建不同的引用,如果是这样,输出是如何生效的?

5 个答案:

答案 0 :(得分:20)

Java管理String文字池。它尽可能地重用这些文字。因此,这两个对象实际上是相同的String对象,==返回true。

我相信这叫做string interning

答案 1 :(得分:6)

==检查变量是否指向对象的完全相同的实例。您创建的两个字符串文字指向内存中的相同位置,因此它们是相等的。字符串文字被实现,因此相同的字符串文字是内存中的同一个对象。

如果你要做

String s = new String("foo");
String t = new String("foo");

然后==将返回false并且s.equals(t)将返回true。

答案 2 :(得分:5)

因为Java Language Specification说:

  

字符串文字 - 或者更一般地说,   作为值的字符串   常数表达式(§15.28) - 是   “实习”以便分享独特   实例,使用该方法   的String.intern。

答案 3 :(得分:5)

这是因为编译器执行了内存优化...即,String常量(即 - String由同一个String文字构成)使用相同的{{1对象,因为String是不可变的。 Strings运算符只检查两个对象是否是同一个实际对象。

如果你能抓住Joshua Bloch和Neal Gafter的Java Puzzlers这本书,看一下拼图13,“动物农场”......他对这个问题有很好的建议。我将复制一些相关文字:

“您可能知道==类型的编译时常量被实现[JLS 15.28]。换句话说,任何两个类型为String的常量表达式都表示相同的字符序列由相同的对象引用...你的代码应该很少,如果有的话,依赖于字符串常量的实习.Interning的设计只是为了减少虚拟机的内存占用,而不是作为程序员的工具...当比较对象引用时,您应该优先使用String方法而不是equals运算符,除非您需要比较对象标识而不是值。“

这是我在上面提到的参考资料......在我的书中第30-31页。

答案 4 :(得分:1)

您没有比较字符串的内容。您只是比较对象的引用。您应该使用equal方法(它是String类的成员)。或者您可以使用compareTo方法(也在相同的String类下)来检查返回值是否为零。

请注意上面的文字更多地是对问题的原始状态的强烈建议,因为看起来OP似乎并不知道幕后的实际过程。

其他人建议进行内部连接是正确的。要回答这个问题,我没有足够的时间去阅读Java Puzzlers的书。我确实怀疑在编译时设置相同的引用,但我不知道如何找到对它的引用。