Defining a method that looks like Object#equals but doesn’t actually override
Object#equals is dangerous. The result of the comparison could differ
depending on the declared type of the argument passed into the equals call.
For example, consider this code:
public class Example {
private int value;
public Example(int value) {
this.value = value;
}
public boolean equals(Example other) {
return this.value == other.value;
}
public static void main(String[] args) {
Example exampleA = new Example(1);
Example exampleB = new Example(1);
System.out.println(exampleA.equals(exampleB));
}
}
This will print true. Suppose you refactor it so that the variable exampleB
is declared as an Object instead. Now this code will print false, because
Java’s overload resolution will choose the default equals(Object)
implementation instead of the equals(Example) method defined in this class.
If this equals method is intended to be a type-specific helper for an equals
method that does override Object#equals, either inline it into the
overriding equals method or rename it to something other than equals to
avoid ambiguity in overload resolution.
If you don’t want to write and maintain equals and hashCode methods by hand,
consider rewriting this class to use
AutoValue.
Suppress false positives by adding the suppression annotation @SuppressWarnings("NonOverridingEquals") to the enclosing element.