如果==比较Java中的引用,为什么它使用这些字符串评估为true?

时间:2010-10-27 13:15:33

标签: java string reference

如上所述,==运算符比较对象引用以检查它们是否引用堆上的同一对象。如果是这样,我为什么要获得这段代码的“平等”?

public class Salmon {
    public static void main(String[] args) {

        String str1 = "Str1";
        String str2 = "Str1";

        if (str1 == str2) {
            System.out.println("Equal");
        } else {
            System.out.println("Not equal");
        }
    }
}

5 个答案:

答案 0 :(得分:37)

该程序将打印Equal(至少使用Sun Hotspot和太阳Javac。)此处在http://ideone.com/8UrRrk

上进行了演示

这是因为字符串文字常量存储在字符串池中,字符串引用可以重复使用。

进一步阅读:


然而:

public class Salmon {
    public static void main(String[] args) {

        String str1 = "Str1";
        String str2 = new String("Str1");

        if (str1 == str2) {
            System.out.println("Equal");
        } else {
            System.out.println("Not equal");
        }
    }
}

将打印Not equal,因为new可以保证引入新的参考。

所以,经验法则:始终使用equals方法比较字符串。

答案 1 :(得分:3)

此代码不会打印Equal 但如果这两个字符串是相同的,这种情况就会很特殊。

现在您已经更新了代码,情况就是这样:

一个简单的(但不是完全准确的)解释是编译器看到两个字符串是相同的并且执行类似的操作:

String str1 = "Str1";
String str2 = str1;

这里真正发生的是编译器将看到文字字符串并将其放在“字符串文字池”中。

由于无法修改字符串(它是不可变的),字符串的字面值(在编译期间找到的字符串)被放在“池”中。
这样,如果两个不同的文字字符串具有相同的内容(如在这种特殊情况下),内存不会浪费两次存储“Str1”和“Str1”。

答案 2 :(得分:3)

Java在运行期间在内部将所有字符串存储在字符串表中。对两个字符串的引用是相同的,因为在内存中它们存储在同一个地方。因此,Equal

您的陈述是正确的,==比较对象引用。尝试与其他任何类相同的东西,但Strings并不会得到相同的结果。

答案 3 :(得分:2)

人们,您忘记了将文字字符串放入池中的过程称为“实习”。 String类有一个名为intern()的方法。此方法将任何字符串放入池中,即使它最初不在池中(不是文字)。这意味着代码如下:

String a = "hello";
String b = new String("hello");
b = b.intern();

System.out.println(a == b);

将打印“true”。 现在,为什么有人需要这个呢?可以想象,如果字符串长度相同但接近末尾不同,字符串比较a.equals(b)可能需要很长时间。 (只需查看.equals()源代码。)。

然而,直接比较引用与比较整数(C语言中的指针)是相同的,这几乎是即时的。

那么,这会给你带来什么?速度。如果您必须多次比较相同的字符串,那么如果您实习这些字符串,您的程序性能将会受益匪浅。但是,如果你只想比较字符串一次,那么就没有性能提升,因为实习过程本身使用了equals()。

我希望这可以解释这一点。

感谢

答案 4 :(得分:0)

上面的评论总结得很好。

我没有方便的Java环境,但尝试以下内容应该为您澄清一些事情(希望这可以按照我的预期进行)。

String str1 = "Str1";  
String str2 = "Str"; str2 += "1";

现在应该打印不等于