Let’s say I have a class called Number, and I intend to do a lot of equality comparisons of Number objects. I am concerned about the “overhead” (class comparison, etc…) of the generic Number::equals(Object o) method. In this case, is it useful to provide a method such as Number::isEqualTo(Number other) as an alternative to Number::equals(Object o)? Is this a common pattern? Or do JVMs currently optimize well enough that there is no advantage to doing this?
Here’s a code example:
public class Number {
int _value;
Number(int value) {
_value = value;
}
@Override
public boolean equals(final Object o) {
if (o == this) return true;
if (o == null) return false;
if (o.getClass() != getClass()) return false;
return isEqualTo((Number)o);
}
public boolean isEqualTo(final Number other) {
return _value == other._value;
}
public static void main(String[] args) {
Number one = new Number(1);
Number two = new Number(2);
if (!one.isEqualTo(two)) {
System.out.println("fast comparison?");
}
if (!one.equals(two)) {
System.out.println("slow comparison?");
}
}
}
You may even provide an overload of
equalsitself:equals(Number). If you implement it very carefully (to be behaviorally indistinguishable fromequals(Object)), you can achieve a minuscule speedup by avoiding a checked downcast in certain cases. Note that you are still going to have to checka.getClass() == b.getClass()so the difference is vanishingly small.