Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does object.equals(new Integer(1)) equate to true?

Tags:

java

I am struggling to understand this Koan:

@Koan
public void equalsMethodCanBeChangedBySubclassesToTestsIfTwoObjectsAreEqual() {
    Object object = new Integer(1);
    assertEquals(object.equals(object), true);
    assertEquals(object.equals(new Integer(1)), __);
    // Note: This means that for the class 'Object' there is no difference between 'equal' and 'same'
    // but for the class 'Integer' there is difference - see below
}

As far as I understand, because object is an instance of the Object class, the .equals() method has not been overwritten, and therefore checks for object equality.

If new Integer(1) creates a new instance, then it should be a separate object to object. Following my train of thought, the correct answer should be false, but only true makes this pass. Where is the flaw in my logic?

Edit: I understand that integers between -128 and 127 are cached. If my understanding of the object object is correct (as stated above), then this is irrelevant.

like image 652
jazzabeanie Avatar asked Nov 30 '22 23:11

jazzabeanie


1 Answers

Integer overrides equals and checks if the underlying int is equal to the int of the other Integer instance, and if so, returns true. The reason why Integer's equals method is invoked, and not the one from Object, is that the runtime type of object is Integer.

Integer is an Object, but due to the overridden equals, no object identity is used.

All following boolean expressions evaluate to true:

    print((new Integer(1).equals(1)));
    print((new Integer(1).equals(new Integer(1))));
    print((((Integer) 1).equals(new Integer(1))));
    print(((Integer) 1).equals(1));

Now consider autoboxing, which reuses instances for values in the range [-128,127]. The following statements about object equality are all evaluating to true:

    1 == ((Integer) 1)
    ((Integer) (-128)) == ((Integer) (-128)) // in autoboxing range
    ((Integer) (+127)) == ((Integer) (+127)) // same

    ((Integer) (-200)) != ((Integer) (-200)) // not autoboxing
    ((Integer) (+200)) != ((Integer) (+200)) // same

    ((Integer) (-128)) != (new Integer(-128)) // explicit new instance, so no autoboxing
    ((Integer) (+127)) != (new Integer(+127)) // same
like image 190
Timmos Avatar answered Dec 05 '22 06:12

Timmos