overriding equals method with same class strategy vs instance of strategy

Viewed 265

Today I come across two different ways of the overriding the equals method. The first one is with same class strategy which is:

public boolean equals(Object aPerson){
    if(aPerson == null) return false;
    if(aPerson.getClass() != this.getClass()) return false;
    Person p = (Person) aPerson;
    return this.name.equals(p.name);
}

and with instance of strategy to be like below:

public boolean equals(Object aPerson){
    if(aPerson == null) return false;
    if(!(aPerson instanceof Person)) return false;
    Person p = (Person) aPerson;
    return this.name.equals(p.name);
}

Do both of the implementation work the same way in any condition? Or do they have exception of working for one some times and not working for the other in special case?

My questions focuses on !(aPerson instanceof Person) and aPerson.getClass() != this.getClass().

2 Answers

There is a difference when it comes to subclasses of Person. The first implementation (Class ==) would consider a Student and a Teacher both named Alice to be different. The second (instanceof) would consider them equal.

Also, using instanceof may violate a contract of the equals() method:

•It is symmetric: for any non-null reference values x and y, x.equals(y) should return true if and only if y.equals(x) returns true.

This can happen if Student overrides equals() and uses instanceOf Student. In that case, checking student.equals(person) may return false, while person.equals(student) returned true.

In general, it depends on your requirement.

Two things:

First, if(aPerson.getClass() != this.getClass()) uses == to compare objects. Yes, theoretically, the "same" class should always result in the same class object, but when different class loaders are in play, strange things could happen. So you would definitely want to use equals() here.

Then: the first one only "matches" when this and aPerson are really objects of the same class. So this is prone to fail, as soon as you are dealing with more than one way how x instanceOf Person could be true. (like Person being an interface with different subclasses).

Related