Java中==和.equals之间的区别。

时间:2011-07-28 20:02:36

标签: java comparison reference

我知道这已被覆盖,但我在SO上看到了不一致的论点。

所以,如果我有:

String a = "apple2e";
String b = "apple2e";

System.out.println("a==b? " + a == b);

FALSE

据我了解,这是因为ab是对同一对象(apple2e)的两个不同引用。

所以我会有类似的东西:

a (reference_id 123) ------
                           ---------  "apple2e"
b (reference_id 456) ------

现在,如果我只想比较两个字符串的内容,我会使用a.equals(b)

这是否意味着如果两个引用指向同一个对象,JVM只是返回?那么它不是真的在进行逐字符比较吗?

由于

修改

拿着手机。感谢delnan指出+优先权!!!

当我将其更改为:

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

我确实得到true

这更有意义。

编辑2

我简直不敢相信。洛尔

我在做:

"a==b? " + a == b

转换为

"a==b? apple2e" == "apple2e"

难怪这是假的!!

7 个答案:

答案 0 :(得分:6)

  

据我了解,这是因为a和b是对同一个对象的两个不同引用(apple2e)。

由于字符串实习,而,因为字符串实习ab是对同一String对象的不同引用。


不幸的是,您的代码没有按照您的想法执行。试试这个:

String a = "apple2e";
String b = "apple2e";

System.out.println("a==b? " + a == b);    // "false"
System.out.println("a==b? " + (a == b));  // "a==b? true"

Java自动实习所有字符串文字。 是第二个sysout打印它的原因。第一个sysout仅打印"false",因为字符串连接(+)的优先级高于==,因此它等同于:

System.out.println("a==b? apple2e" == "apple2e");

我认为这不是你要测试的意思!

另一方面,这将为您提供两个单独的String个实例:

String a = new String("apple2e");
String b = new String("apple2e");

System.out.println("a==b? " + (a == b));  // "a==b? false"

这将示意性地看起来像

a (reference_id 123) ---------------  "apple2e"

b (reference_id 456) ---------------  "apple2e"

可以使用String#intern()缩小到原始状态:

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

System.out.println("a==b? " + (a == b));  // "a==b? true"

e.g。

a (reference_id 123) ------+
                           +---------  "apple2e"
b (reference_id 456) ------+

答案 1 :(得分:6)

你的第一个例子确实如此。 println中的表达式并没有达到您的意思。

String a = "apple2e";
String b = "apple2e";

System.out.println("a==b? " + (a == b));

将打印a==b? true注意所有重要的分组!

你是对的,a和b是对同一个对象的两个不同的引用。这正是为什么在测试时==返回true的原因! ==测试两个不同的指针是否指向内存中的相同位置。 a和b都是对内存中相同位置的引用,它保存了interned编译时间“apple2e”字符串。

现在,如果你这样做了

String a = new String("apple2e");
String b = new String("apple2e");

System.out.println("a==b? " + (a == b));

它实际上会打印a==b? false。因为你在内存中创建了两个不同的对象,a和b指向不同的地方。

答案 2 :(得分:5)

'a'和'b'是相同的参考,问题是你没有比较a和b。你应该期待

a==b? false

但你得到了

false

这是因为+优先于==,所以你拥有的是

System.out.println(("a==b? " + a) == b);

以同样的方式,您希望以下内容打印为true。

System.out.println(1 + 2 == 3);

您需要的是

System.out.println("a==b? " + (a == b));

答案 3 :(得分:4)

a == b查看两个对象是否指向内存中的同一对象。因为他们没有,即使他们的内部是相同的,a == b将是错误的。 1 == 1将是真的,因为整数是原始变量,而字符串实际上是对象。

a.equals(b)是一个实例方法,它在内部检查两个字符串是否具有相同的字符。

如果你这样做了:

String a = "hello";
String b = a;

那么 a == b就是真的。

答案 4 :(得分:1)

apple2e不是对象。它是引用指向的值。

String a = "apple2e";
String b = "apple2e";

此处,ab是存储在两个不同位置的值apple2e的对象(引用)。

答案 5 :(得分:1)

a和b是对同一对象的两个不同引用 - PROBABLY

"a==b? " + a

计算字符串“a == b?apple2e” 这与字符串“apple2e”

绝对不一样(==或等于)

所以你的代码:

System.out.println("a==b? " + a == b);

只是测试“a == b?apple2e”是否与“apple2e”相同而不是(无论你如何定义)。

答案 6 :(得分:1)

如果更改为以下内容: System.out.println("a==b? " + (a == b));

你得到了 a==b? true

这里发生的事情是a和b都指向由String类维护的字符串的内部缓存。

这是String.equals()

的实现
public boolean equals(Object anObject) {
if (this == anObject) {
    return true;
}
if (anObject instanceof String) {
    String anotherString = (String)anObject;
    int n = count;
    if (n == anotherString.count) {
    char v1[] = value;
    char v2[] = anotherString.value;
    int i = offset;
    int j = anotherString.offset;
    while (n-- != 0) {
        if (v1[i++] != v2[j++])
        return false;
    }
    return true;
    }
}
return false;
}

anObject必须是String才能返回true,如果它是对同一个Object的引用,则它会立即返回true。 否则,正如你所看到的那样,是通过字符比较进行角色。