CompareTo Parameter Type Mismatch
ID |
java.compareto_overloaded |
Severity |
high |
Remediation Complexity |
medium |
Remediation Risk |
low |
Remediation Effort |
medium |
Resource |
Code Smell |
Language |
Java |
Tags |
reliability |
Description
Reports a compareTo method whose single parameter type does not match the type argument
declared on the class’s Comparable<T> (directly, or inherited from a superclass). Such a
method does not override Comparable.compareTo(T) — it overloads it with an unrelated method
that code going through the Comparable interface will never call.
Rationale
The compiler happily accepts an extra compareTo overload alongside (or instead of) the real
override, because overloading by parameter type is legal Java. Nothing marks the mistake: no
@Override is required, no error, no warning. But any code that sorts, compares, or stores the
object through Comparable<T> — Collections.sort, a TreeSet, a TreeMap — calls
compareTo(T) on the declared type parameter, silently bypassing the mismatched overload and
falling back to the inherited implementation (or failing to compile against generics elsewhere).
class Version implements Comparable<Version> {
public int compareTo(Version other) { /* ... */ return 0; }
}
class PatchVersion extends Version {
public int compareTo(PatchVersion other) { // Wrong: overloads, does not override
return 0;
}
}
PatchVersion now has two compareTo methods. Any caller holding a Version reference —
which is exactly what Comparable<Version> promises — invokes the inherited one, and the new
overload is dead code that only fires when someone happens to call it with the exact static
type PatchVersion.
Remediation
Declare the parameter with the same type the class’s Comparable<T> uses:
class PatchVersion extends Version {
@Override
public int compareTo(Version other) { // Correct: overrides Comparable<Version>
return 0;
}
}
Always add @Override on compareTo — the compiler will then reject a parameter type that
does not match, turning this class of mistake into a build failure instead of a silent overload.