I'm using Eclipse to generate .equals()
and .hashCode()
, and there is an option labeled "Use 'instanceof' to compare types". The default is for this option to be unchecked and use .getClass()
to compare types. Is there any reason I should prefer .getClass()
over instanceof
?
Without using instanceof
:
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Using instanceof
:
if (obj == null)
return false;
if (!(obj instanceof MyClass))
return false;
I usually check the instanceof
option, and then go in and remove the "if (obj == null)
" check. (It is redundant since null objects will always fail instanceof
.) Is there any reason that's a bad idea?
It depends if you consider if a subclass of a given class is equals to its parent.
here I would use 'instanceof', because I want a LastName to be compared to FamilyName
here I would use 'getClass', because the class already says that the two instances are not equivalent.
Both methods have their problems.
If the subclass changes the identity, then you need to compare their actual classes. Otherwise, you violate the symmetric property. For instance, different types of
Person
s should not be considered equivalent, even if they have the same name.However, some subclasses don't change identity and these need to use
instanceof
. For instance, if we have a bunch of immutableShape
objects, then aRectangle
with length and width of 1 should be equal to the unitSquare
.In practice, I think the former case is more likely to be true. Usually, subclassing is a fundamental part of your identity and being exactly like your parent except you can do one little thing does not make you equal.
instanceof works for instences of the same class or its subclasses
ArryaList and RoleList are both instanceof List
While
getClass() == o.getClass() will be true only if both objects ( this and o ) belongs to exactly the same class.
So depending on what you need to compare you could use one or the other.
If your logic is: "One objects is equals to other only if they are both the same class" you should go for the "equals", which I think is most of the cases.
If you use
instanceof
, making yourequals
implementationfinal
will preserve the symmetry contract of the method:x.equals(y) == y.equals(x)
. Iffinal
seems restrictive, carefully examine your notion of object equivalence to make sure that your overriding implementations fully maintain the contract established by theObject
class.Josh Bloch favors your approach:
See also this SO answer.
Effective Java chapter 3 also covers this.
This is something of a religious debate. Both approaches have their problems.
Bloch has another relevant piece of advice in Effective Java Second Edition: