All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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