
errorprone.bugpattern.SuperCallToObjectMethod.md Maven / Gradle / Ivy
The newest version!
Implementations of `equals` and `hashCode` should usually not delegate to
`Object.equals` and `Object.hashCode`.
Those two methods implement equality based on object identity. That
implementation *is* sometimes what the author intended. (This check attempts to
identify those cases and *not* report a warning for them. But in some cases, it
still produces a warning when it shouldn't.)
But when `super.equals` and `super.hashCode` call the methods defined in
`Object`, the developer often did *not* intend to use object identity. Often,
developers write something like:
```java
private final int id;
@Override
public boolean equals(Object obj) {
if (obj instanceof Foo) {
return super.equals(obj) && id == ((Foo) obj).id;
}
return false;
}
@Override
public int hashCode() {
return super.hashCode() ^ id;
}
```
This appears to be an attempt to define equality in terms of the `id` field in
this class and any fields in the superclass. However, when the superclass that
defines `equals` or `hashCode` is `Object`, the code instead defines equality in
terms of a mix of object identity and field values. The result is equivalent to
defining it in terms of identity alone—which is equivalent to not overriding
`equals` and `hashCode` at all!
Typically, the code should be rewritten to remove the `super` calls entirely:
```java
private final int id;
@Override
public boolean equals(Object obj) {
if (obj instanceof Foo) {
return id == ((Foo) obj).id;
}
return false;
}
@Override
public int hashCode() {
return id;
}
```
Note that the suggested edits for this check instead preserve behavior, which
likely means preserving bugs! However, in cases in which object identity *is*
intended, we recommend applying the suggested edit to make that behavior
explicit in the code:
```java
// This class's definition of equality is unusual and perhaps not ideal.
// But it is at least explicit.
private final Integer id;
@Override
public boolean equals(Object obj) {
if (obj instanceof Foo) {
if (id == null) {
return this == obj;
}
return id.equals(((Foo) obj).id);
}
return false;
}
@Override
public int hashCode() {
return id != null ? id : System.identityHashCode(this);
}
```
© 2015 - 2025 Weber Informatics LLC | Privacy Policy