Default Methods


Idioms and Techniques

Design Rationale

Advanced Questions

Why can’t default methods override equals, hashCode, and toString?

An interface cannot provide a default implementation for any of the methods of the Object class. This is a consequence of the “class wins” rule for method resolution: a method found on the superclass chain always takes precedence over any default methods that appear in any superinterface. In particular, this means one cannot provide a default implementation for equals, hashCode, or toString from within an interface.

This seems odd at first, given that some interfaces actually define their equals behavior in documentation. The List interface is an example. So, why not allow this?

One reason is that it would become more difficult to reason about when a default method is invoked. The current rules are simple: if a class implements a method, that always wins over a default implementation. Since all instances of interfaces are subclasses of Object, all instances of interfaces have non-default implementations of equals, hashCode, and toString already. Therefore, a default version of these on an interface is always useless, and it may as well not compile.

Another reason is that providing default implementations of these methods in an interface is most likely misguided. These methods perform computations over the object’s state, but the interface, in general, has no access to state; only the implementing class has access to this state. Therefore, the class itself should provide the implementations, and default methods are unlikely to be useful.

For further reading, see this explanation written by Brian Goetz in response to “Allow default methods to override Object’s methods” on the lambda-dev mailing list in March, 2013.