如何在Java中实现==运算符?

时间:2009-09-05 00:09:20

标签: java jvm

具体来说,在对象引用相等的情况下,==运算符会做什么?

如果引用在比较时计算到同一个对象地址,比较是否返回true?或者它是否利用两个引用的hashCode值来确定对象是否相同?

在这里非常具体,我想知道由JVM管理的数据结构被==操作引用以进行参考比较。 ==依靠OOP来执行参考比较吗?

对我来说不幸的是JLS does not define how the == operator must work。 Java API文档没有提到==应该做什么(它们是针对类的,对吧?)

PS:我对hashcode uniqueness上的这个问题有点兴趣,并且更愿意知道Sun JVM(或OpenJDK)如何实现==运算符。

4 个答案:

答案 0 :(得分:10)

==运算符只是比较引用。

JVM中的引用只是一个标准对象指针。这可以解决单个32位或64位整数值(取决于平台)。

当你比较两个对象引用时,你实际上只是比较两个32位或64位整数,如果它们是相同的,你就等于相等。整数值是内存中的一个位置。

答案 1 :(得分:3)

因为参考只是一个数字,所以参考比较结果只是比较两个数字。不需要哈希。

答案 2 :(得分:2)

==运算符比较对象引用以查看它们是否相同,即它们引用内存中的同一对象。

equals()方法比较对象引用以查看它们是否相同,但不一定相同。 equals()的默认实现使用==运算符,但覆盖此行为通常是有意义的。例如,如果两个BankAccount引用具有相同的帐号,则可能需要将它们视为等效,即使它们是完全不同的对象。

答案 3 :(得分:0)

如果对象是同一个对象,则==运算符返回true。这里无法访问hashCode()或equals()。

尝试此确认:

public class Test {
    static void testEqualEqual(Integer I0, Integer I1, boolean IsEquals) {
        if(!(IsEquals == (I0 == I1)))
            throw new AssertionError();
    }
    static void testEqual(Integer I0, Integer I1, boolean IsEquals) {
        if(!(IsEquals == (I0.equals(I1))))
            throw new AssertionError();
    }
    static void testHash(Integer I0, Integer I1, boolean IsEquals) {
        if(!(IsEquals == (I0.hashCode() == I1.hashCode())))
            throw new AssertionError();
    }

    public static void main(String ... args) {
        testEqualEqual(   1,    1, true);
        testEqualEqual(2000, 2000, false);

        testEqual(   1,    1, true);
        testEqual(2000, 2000, true);

        testHash(   1,    1, true);
        testHash(2000, 2000, true);
        System.out.println("Done");
    }
}

要理解这一点,首先应该知道在自动装箱时将缓存数字255。这意味着1的整数始终是同一个对象,但2000的整数始终是不同的对象。

此实验表明,当对象相同时,'=='返回true。如果是'1',它们是相同的数字,它返回true。但是在'2000'的情况下,autoboxed是不同的对象,所以它返回false。

实验还表明'=='不使用equals()或hashCode()。

希望这有帮助。