(unless you really override
Object.equals(), of course).
I’ve stumbled upon a rather curious
Stack Overflow question by user Frank:
Why does Java’s Area#equals method not override Object#equals?
Interestingly, there is a
Area.equals(Area) method which really takes an
Area argument, instead of a
Object argument as declared in
Object.equals(). This leads to rather nasty behaviour, as discovered by Frank:
@org.junit.Test
public void testEquals() {
java.awt.geom.Area a = new java.awt.geom.Area();
java.awt.geom.Area b = new java.awt.geom.Area();
assertTrue(a.equals(b)); // -> true
java.lang.Object o = b;
assertTrue(a.equals(o)); // -> false
}
Technically, it is correct for AWT’s Area to have been implemented this way (as
hashCode() isn’t implemented either), but the way Java resolves methods, and the way programmers digest code that has been written like the above code, it is really a terrible idea to overload the equals method.
No static equals, either
These rules also hold true for static
equals() methods, such as for instance
Apache Commons Lang‘s
ObjectUtils.equals(Object o1, Object o2)
The confusion here arises by the fact that you cannot static-import this equals method:
import static org.apache.commons.lang.ObjectUtils.equals;
When you now type the following:
You will get a compiler error:
The method equals(Object) in the type Object is not applicable for the arguments (…, …)
The reason for this is that methods that are in the scope of the current class and its super types will always shadow anything that you import this way. The following doesn’t work either:
import static org.apache.commons.lang.ObjectUtils.defaultIfNull;
public class Test {
void test() {
defaultIfNull(null, null);
// ^^ compilation error here
}
void defaultIfNull() {
}
}
Details in this Stack Overflow question.
Conclusion
The conclusion is simple.
never overload any of the methods declared in Object (overriding is fine, of course). This includes:
clone()
equals()
finalize()
getClass()
hashCode()
notify()
notifyAll()
toString()
wait()
Of course, it would be great if those methods weren’t declared in
Object in the first place, but that ship has sailed 20 years ago.