Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is it better to use the default Object equals method in Java?

Why is it considered better to use the default Object equals method in Java and modify it so it will work for a specific class (by validating with instanceof and using type casting):

public boolean equals(Object otherObject)
{
   boolean isEqual = false;

   if ((otherObject != null) && (otherObject instanceof myClass))
      {
         myClass classObject = (myClass)otherObject;

         if (.....) //checking if equal
         {
            .....
}

instead of overloading it with a new equals method specific for each class that needs to use equals:

public boolean equals(myClass classObject)
like image 583
tempy Avatar asked Nov 25 '12 16:11

tempy


2 Answers

The signature of Object.equals() is public boolean equals(Object). If you define a method public boolean equals(MyClass), you're adding a new method, with a different signature, instead of overriding (or redefining, if you prefer) the Object.equals() method.

Since all the collections call the Object.equals() method, your new method would never be called by anybody except your own code, and would thus be almost useless. For example, if you create a Set<MyClass>, it will consider that two instances are different, although your equals(MyClass) method considers them equal.

like image 111
JB Nizet Avatar answered Nov 15 '22 05:11

JB Nizet


It is because most classes in Java (lists, queues, maps etc.) use the boolean equals(Object obj) method. At the time when Java was being designed way back in the nineties, Generics did not exist.

Comparison methods using for example the Comparator or Comparable, were updated to support generics, and thus take the right type (avoiding the instanceof) of your class directly. Object.equals() just takes a generic Object.

If you overload .equals() with new signatures, the other collections won't know about your new equals() methods and will still call the old original one provided by Object, so you have to stick with that and use instanceof. Remember overloading does not have the same effect of overriding. In overriding the subclass method gets called, since it has exactly the same signature. In overloading, you are just providing alternative functionality with a different signature, so the caller has to know about it.

Alternatively, instead of using the equals() method, maybe you can change your code a little to use the newer comparison methods with generics. Most collections have been updated to support Comparator, Comparable etc. with Generics too.

like image 29
jbx Avatar answered Nov 15 '22 05:11

jbx