tags:

views:

384

answers:

4

Specifically, in the case of object reference equality, what does the == operator do?

Does the comparison return true if the references evaluate to the same object address at the time of comparison? Or does it utilize the hashCode value of the two references to determine if the objects are the same?

To be very specific here, I would like to know what data structures managed by the JVM are referenced by the == operation for reference comparison. Does == rely on the OOP to perform reference comparison?

Unfortunately for me, the JLS does not define how the == operator must work. The Java API docs do not mention what == is supposed to do (they're for classes, right?)

PS: I was a bit intrigued by this question on hashcode uniqueness, and would prefer to know how the Sun JVM (or OpenJDK) implements the == operator.

+2  A: 

Because a reference is just a number, a reference comparison comes down to just comparing two numbers. No hash is needed.

Mike Daniels
The way I understand it, the JVM stores information about each object in an OOP (ordinary object pointer). I would like to know if the == operator uses this information or not.
Vineet Reynolds
To put it in better words, where does the == implementation get this reference value for usage in comparison?
Vineet Reynolds
@Vineet: Check my answer for more details about how the number is "generated" - the pointer IS a number.
Reed Copsey
+2  A: 

The == operator compares object references to see if they are identical, i.e. they refer to the same object in memory.

The equals() method compares object references to see if they are equivalent, though not necessarily identical. The default implementation of equals() uses the == operator, but it often makes sense to override this behavior. For example, you might want two BankAccount references to be considered equivalent if they have the same account number, even if they are completely different objects.

SingleShot
+5  A: 

The == operator just compares the references.

References in the JVM are just a standard object pointer. This works out to a single 32bit or 64bit integer value (depending on platform).

When you compare two object references, you're really just comparing two 32bit or 64bit integers, and if they're the same, you'll equate to equal. The integer values are a location in memory.

Reed Copsey
Reed, I get what you are saying. Would like to know where in the JVM sources can I find the implementation of the == operator? Any pointers would help.
Vineet Reynolds
I'm afraid this is entering C/C++ territory.
Vineet Reynolds
You'd have to look at the implementation of java.Lang.Object's equals method: http://java.sun.com/j2se/1.3/docs/api/java/lang/Object.html#equals%28java.lang.Object%29
Reed Copsey
I believe there is some misunderstanding of my comments. If I refer to the equals method implementation, I find a (this==obj) comparison. In actuality, I would like to know where the object pointers are stored by the JVM itself, so that when the addresses are compared, they will return true or false.
Vineet Reynolds
Oops, sorry. I missed the part where you said that references are standard object pointers. Does this imply that the JVM compares two OOP objects for implementing == ?
Vineet Reynolds
Yes. They're just numbers, since pointers are just an int value specifying a memory location.
Reed Copsey
I finally get it. The == operation translates to the if_acmpne instruction in bytecode; during execution this pops off the object references from the operand stack and compares them. I still haven't figure out how the references are obtained in the first place. But that can wait.
Vineet Reynolds
A: 

The == operator returns true if the objects are the same object. There is not access to hashCode() or equals() here.

Try this to confirm:

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");
    }
}

To understand this, you should know first that the number number 255 will be cached when autoboxed. This means that Interger of 1 is always the same object but Integer of 2000 will always be differetn object.

This experiment shows that '==' return true when the objects are the same. In case of '1' they are the same number and it returns true. But in case of '2000' autoboxed to be different objects so it returns false.

The experiment also shows that '==' does not use equals() or hashCode().

Hope this helps.

NawaMan
Thanks, the use of the Integer wrapper class' caching property was pretty clever. However, I was more interested in knowing the actual classes and data structure inside the JVM where the object reference is stored, and eventually used in a reference comparison operation.
Vineet Reynolds
I see what you means now but I am afraid the answer will vastly depends on what JVM you are looking at. I think each JVM has different internal structure (though implementing the same specification).If you really want to know, checkout the source code of the <a href="http://download.java.net/openjdk/jdk7/">OpenJDK</a>.:D
NawaMan