Bugs: Don't use co-variant equals and compareTo

Overview

When it comes to comparing objects it is tempting to write in class A; equals(A) or compareTo(A). However these methods may not be called the way you expect if they don't overridden the default equals(Object) or compareTo(Object)

Don't implement equals(Class)

From Area
public boolean equals(Area area) {
}
The problem is that many methods expect to call equals(Object) and won't call this method.

Area a = new Area();
Object o = a;
Area a2 = (Area) a.clone();
System.out.println("a.equals(o) is "+a.equals(o));
System.out.println("a2.equals(o) is "+a2.equals(o));
System.out.println("a2.equals(a) is "+a2.equals(a));

List areas = new ArrayList();
areas.add(a);
System.out.println("areas.contains(a) is "+areas.contains(a));
System.out.println("areas.contains(a2) is "+areas.contains(a2));
prints
a.equals(o) is true
a2.equals(o) is false
a2.equals(a) is true
areas.contains(a) is true
areas.contains(a2) is false

Don't use compareTo for other purposes

In most cases, compareTo is used for Comparable, however it is confusing when this method is used differently.

from SnmpIndex
// @return the value 0 if the two OID vectors have the same elements, another value otherwise
public int compateTo(SnmpIndex index) {
This method has more in common with an equals method as it doesn't define a greater than or less than relationship.

The class already has an equals() method do I would suggest removing this method or making it comply with the Comparable standard. It doesn't appear to be used anywhere in the JDK so it is possible its not used anywhere as the class is not Comparable.

Conclusion

Always implement equals(Object) and compareTo(Object) or compareTo(C) if using generics. Otherwise, it may not be clear when your method is called.

Comments

Popular posts from this blog

Java is Very Fast, If You Don’t Create Many Objects

Low Latency Microservices, A Retrospective

Unusual Java: StackTrace Extends Throwable