4

Suppose I have 2 equals method in the circle class,

public boolean equals(Object obj);
public boolean equals(Circle circle);

And I do this:

Circle c1 = new Circle(new Point(0, 0), 10);
Circle c2 = new Circle(new Point(0, 0), 10);
Object o1 = c1;
Object o2 = c2;

For o1.equals(c1); why does it call the equals(Object obj) instead of equals(Circle circle)?

  • Does this answer your question? [Method overload resolution in java](https://stackoverflow.com/questions/30109231/method-overload-resolution-in-java) – Smile Aug 27 '20 at 03:53
  • "Why"? Because it's specified that way. If you want to know why they specified it that way, you'd have to ask somebody from Sun Microsystems in the early 1990es. –  Aug 27 '20 at 04:02
  • You should not have an equals(Circle) method. It can create confusion. And please don't forget to override hashCode() also. – NomadMaker Aug 27 '20 at 05:26
  • 2
    I love the ambiguity of the title of your question :D – Erich Kitzmueller Aug 27 '20 at 07:40

2 Answers2

3

The declared type decide what kinds of methods you can call, the real type decide what implementationi to use.
If you call o1.equals(c1), because the decalred type is Object,the compiler will find method in Object to use which is equals(Object obj).
if you call c2.equals(c1), this time the declared type is Circle, the compiler will find that equals(Circle) is better than equals(Object) with java's method overload resolution mechanism.

In fact you can view the two equals method as two totally different method which happens to have same name.

haoyu wang
  • 1,241
  • 4
  • 17
0

This exact scenario is described in Effective Java. From page 49 of the third edition,

Don’t substitute another type for Object in the equals declaration. It is not uncommon for a programmer to write an equals method that looks like this and then spend hours puzzling over why it doesn’t work properly:

// Broken - parameter type must be Object!
public boolean equals(MyClass o) {
    ...
}

The problem is that this method does not override Object.equals, whose argument is of type Object, but overloads it instead. It is unacceptable to provide such a “strongly typed” equals method even in addition to the normal one, because it can cause Override annotations in subclasses to generate false positives and provide a false sense of security.

jaco0646
  • 15,303
  • 7
  • 59
  • 83