Implementations of equals that use instanceof to check the type of their argument are likely to lead to non-symmetric definitions of equals, if they are further overridden in subclasses that add fields and redefine equals. A definition of the equals method should be reflexive, symmetric, and transitive, and a violation of the equals contract may lead to unexpected behavior.

Consider using one of the following options:

The first option has the disadvantage of violating the substitution principle of object-oriented languages, which says that an instance of a subclass of A can be provided whenever an instance of class A is required.

The first option is illustrated in the following example:

Given the definitions in the example, p.equals(q) returns true whereas q.equals(p) returns false, which violates the symmetry requirement of the equals contract.

Attempting to enforce symmetry by modifying the BadPointExt.equals method to ignore the field s when its parameter is an instance of type BadPoint results in violating the transitivity requirement of the equals contract.

The classes GoodPoint and GoodPointExt avoid violating the equals contract by using getClass rather than instanceof.

  • J. Bloch, Effective Java (second edition), Items 8 and 16. Addison-Wesley, 2008.
  • Java API Documentation: Object.equals().
  • The Java Language Specification: Type Comparison Operator instanceof.
  • Artima Developer: How to Write an Equality Method in Java.
  • JavaSolutions, April 2002: Secrets of equals().