如果==比较Java中的引用,为什么用这些字符串计算为true?

如果==比较Java中的引用,为什么用这些字符串计算为true?,java,string,reference,Java,String,Reference,如上所述,==运算符比较对象引用以检查它们是否引用堆上的同一对象。如果是这样的话,为什么我会得到这段代码的“相等” public class Salmon { public static void main(String[] args) { String str1 = "Str1"; String str2 = "Str1"; if (str1 == str2) { System.out.println("Equ

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

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");
        }
    }
}
此代码不会打印
Equal

但是如果这两个字符串是相同的,那么这种情况将是特殊的

现在,您已经更新了代码,情况如下:

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

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

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

由于字符串不能修改(它是不可变的),字符串的文本值(在编译过程中找到的)被放入“池”中。

这样,如果两个不同的文本字符串具有相同的内容(如在本例中),则不会浪费内存来存储“Str1”和“Str1”两次。

Java在运行期间内部存储字符串表中的所有字符串。对这两个字符串的引用是相同的,因为它们在内存中存储在同一个位置。因此,
等于


您的陈述是正确的,
=
比较对象引用。对任何其他类尝试相同的操作,但不使用字符串,您将不会得到相同的结果。

程序将打印
相等的
(至少使用Sun Hotspot和Sun Javac)。此处在

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

进一步阅读:


然而,这是:

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");
        }
    }
}
将打印
不相等
,因为
新建
保证引入新的参考


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

上面的注释对其进行了很好的总结

我手头没有Java环境,但是尝试下面的内容应该可以为您澄清一些事情(希望这能像我预期的那样起作用)


如果现在打印的不是相等的人,您忘记了在池中放置文本字符串的过程称为“interning”。类字符串有一个名为intern()的方法。此方法将任何字符串放入池中,即使它最初不在池中(不是文本)。这意味着像这样的代码:

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

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

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

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

我希望这能解释这一点


谢谢

您确定使用了
=
=
吗?更改了一个代码示例,请务必说语言是JAVA。其他语言将有其他实现。无论==运算符重载为.net做什么,==都会在检查对象是否相等的情况下检查引用是否相同。字符串对象是如何创建的参见-它是如何创建的?你能给我一个支持这一主张的参考吗?aioobe给出了一个更好的解释,因为这种行为是不能保证的。而且它也只适用于字符串文字,而不是程序中的每个字符串。从Java API文档中可以看出:“所有文字字符串和字符串值常量表达式都被暂存。”请注意,只有常量字符串会被自动暂存。您可以通过调用String.intern()+1链接到ideone.com来插入动态创建的字符串。很长一段时间以来,我一直想要这样的网络应用。我甚至想过自己写,但它确实存在。为了完整性
新字符串(“Str1”)。intern()
也会打印“Equal:)
String a = "hello";
String b = new String("hello");
b = b.intern();

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