What’s the reasoning behind decision to include these methods in the java.lang.Object? Equality and hashing doesn’t make sense for many classes.
It would be more logical to make two interfaces:
interface Equalable {
boolean equals(Equalable other);
}
interface Hashable extends Equalable {
int hashCode();
}
For example HashSet definition might look like
class HashSet<T extends Hashable> ...
It would prevent one of the common beginner mistakes – using set of items without implementing equals/hashCode.
When we implement an interface we inject (or accept) the contract defined by the interface.
Equalable&Hashableare two different contracts. But if we take a look closely then we will see that both of them depend on each other, which means they are part of asingle interface, something likeEqualableAndHashable.Now the obvious question is, whether they should be part of this new
EqualableAndHashableinterface orObject?Let’s find out. We have
==(equal operator) to check equality of two objects.==operator confirms whether values/references are equal for two different primitives/objects. But this is not always possible to answer just by checking with the==operator.Now question is, whether this equality, which is also a contract, should be injected via interfaces or part of the Object class?
If we take a look, we can’t just say something like:
It will become a chaos if some object types offer equality and some do not. Which means object of
TypeXmust honor the equality contract which is true for all other object types as well. So, it must not inject equality from a interface, because equality should be the part of the contract for any object by default, otherwise it will create chaos.So we need Objects to come up with implementation of
equals. But it can’t implement only theequalsmethod, it also needs to implement thehashcodemethod.