
org.sonar.l10n.java.rules.java.S2160.html Maven / Gradle / Ivy
This rule raises an issue when a subclass of a class that overrides Object.equals
introduces new fields but does not also override the
Object.equals
method.
Why is this an issue?
When a class overrides Object.equals
, this indicates that the class not just considers object identity as equal (the default
implementation of Object.equals
) but implements another logic for what is considered equal in the context of this class. Usually (but not
necessarily), the semantics of equals
in this case is that two objects are equal when their state is equal field by field.
Because of this, adding new fields to a subclass of a class that overrides Object.equals
but not updating the implementation of
equals
in the subclass is most likely an error.
How to fix it
Consider the following example:
class Foo {
final int a;
@Override
public boolean equals(Object other) {
if (other == null) return false;
if (getClass() != other.getClass()) return false;
return a == ((Foo) other).a;
}
}
class Bar extends Foo { // Noncompliant, `equals` ignores the value of `b`
final int b;
}
Override the equals
method in the subclass to incorporate the new fields into the comparison:
class Bar extends Foo { // Compliant, `equals` now also considers `b`
final int b;
@Override
public boolean equals(Object other) {
if (!super.equals(other)) return false;
return b == ((Bar) other).b;
}
}
In case the new fields should not be part of the comparison because they are, for example, auxiliary variables not contributing to the object value
(), still override the method to make the point clear that this was not just forgotten:
class Bar extends Foo { // Compliant, we do explicitly not want to take `b` into account
final int b;
@Override
public boolean equals(Object other) {
return super.equals(other);
}
}
Resources
Documentation