Accepted answer

if you use instanceof, making your equals implementation final will preserve the symmetry contract of the method: x.equals(y) == y.equals(x). if final seems restrictive, carefully examine your notion of object equivalence to make sure that your overriding implementations fully maintain the contract established by the object class.

what i'm trying to get at here is that if you believe getclass() is the only reliable way to preserve symmetry, you are probably using equals() the wrong way.

sure, it's easy to use getclass() to preserve the symmetry required of equals(), but only because x.equals(y) and y.equals(x) are always false. liskov substitutability would encourage you to find a symmetry-preserving implementation that can yield true when it makes sense. if a subclass has a radically different notion of equality, is it really a subclass?


actually instanceof check where an object belongs to some hierarchy or not. ex: car object belongs to vehical class. so "new car() instance of vehical" returns true. and "new car().getclass().equals(vehical.class)" return false, though car object belongs to vehical class but it's categorized as a separate type.


instanceof works for instences of the same class or its subclasses

you can use it to test if an object is an instance of a class, an instance of a subclass, or an instance of a class that implements a particular interface.

arryalist and rolelist are both instanceof list


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.


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 persons 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 immutable shape objects, then a rectangle with length and width of 1 should be equal to the unit square.

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.


if you want to ensure only that class will match then use getclass() ==. if you want to match subclasses then instanceof is needed.

also, instanceof will not match against a null but is safe to compare against a null. so you don't have to null check it.

if ( ! (obj instanceof myclass) ) { return false; }


it depends if you consider if a subclass of a given class is equals to its parent.

class lastname

class familyname
extends lastname

here i would use 'instanceof', because i want a lastname to be compared to familyname

class organism

class gorilla extends organism

here i would use 'getclass', because the class already says that the two instances are not equivalent.


correct me if i am wrong, but getclass() will be useful when you want to make sure your instance is not a subclass of the class you are comparing with. if you use instanceof in that situation you can not know that because:

class a { }

class b extends a { }

object oa = new a();
object ob = new b();

oa instanceof a => true
oa instanceof b => false
ob instanceof a => true // <================ here
ob instanceof b => true

oa.getclass().equals(a.class) => true
oa.getclass().equals(b.class) => false
ob.getclass().equals(a.class) => false // <===============here
ob.getclass().equals(b.class) => true


this is something of a religious debate. both approaches have their problems.

  • use instanceof and you can never add significant members to subclasses.
  • use getclass and you violate the liskov substitution principle.

bloch has another relevant piece of advice in effective java second edition:

  • item 17: design and document for inheritance or prohibit it


the reason to use getclass is to ensure the symmetric property of the equals contract. from equals' javadocs:

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.

by using instanceof, it's possible to not be symmetric. consider the example: dog extends animal. animal's equals does an instanceof check of animal. dog's equals does an instanceof check of dog. give animal a and dog d (with other fields the same):

a.equals(d) --> true
d.equals(a) --> false

this violates the symmetric property.

to strictly follow equal's contract, symmetry must be ensured, and thus the class needs to be the same.


angelika langers secrets of equals gets into that with a long and detailed discussion for a few common and well-known examples, including by josh bloch and barbara liskov, discovering a couple of problems in most of them. she also gets into the instanceof vs getclass. some quote from it


having dissected the four arbitrarily chosen examples of implementations of equals() , what do we conclude?

first of all: there are two substantially different ways of performing the check for type match in an implementation of equals() . a class can allow mixed-type comparison between super- and subclass objects by means of the instanceof operator, or a class can treat objects of different type as non-equal by means of the getclass() test. the examples above illustrated nicely that implementations of equals() using getclass() are generally more robust than those implementations using instanceof .

the instanceof test is correct only for final classes or if at least method equals() is final in a superclass. the latter essentially implies that no subclass must extend the superclass's state, but can only add functionality or fields that are irrelevant for the object's state and behavior, such as transient or static fields.

implementations using the getclass() test on the other hand always comply to the equals() contract; they are correct and robust. they are, however, semantically very different from implementations that use the instanceof test. implementations using getclass() do not allow comparison of sub- with superclass objects, not even when the subclass does not add any fields and would not even want to override equals() . such a "trivial" class extension would for instance be the addition of a debug-print method in a subclass defined for exactly this "trivial" purpose. if the superclass prohibits mixed-type comparison via the getclass() check, then the trivial extension would not be comparable to its superclass. whether or not this is a problem fully depends on the semantics of the class and the purpose of the extension.


josh bloch favors your approach:

the reason that i favor the instanceof approach is that when you use the getclass approach, you have the restriction that objects are only equal to other objects of the same class, the same run time type. if you extend a class and add a couple of innocuous methods to it, then check to see whether some object of the subclass is equal to an object of the super class, even if the objects are equal in all important aspects, you will get the surprising answer that they aren't equal. in fact, this violates a strict interpretation of the liskov substitution principle, and can lead to very surprising behavior. in java, it's particularly important because most of the collections (hashtable, etc.) are based on the equals method. if you put a member of the super class in a hash table as the key and then look it up using a subclass instance, you won't find it, because they are not equal.

see also this so answer.

effective java chapter 3 also covers this.

Related Query

More Query from same tag