重写超类或子类中的 equals 和 hashCode 方法,或者重写两者

dav*_*veb 2 java equals hashcode

我对java编程比较陌生,当我有一个从超类继承的子类时,我在寻找在哪里使用 equals 和 hashcode 方法重写时遇到了问题。

我想检查超类和子类的对象是否相等,并且想知道超类和子类中的一个或两个是否需要重写它们的 equals 和 hashcode 方法?

我的子类没有实例变量,我的超类有 2 个实例变量(整数)

我的子类构造函数正在调用超类构造函数。

如果我想重写子类的 equals 和 hashcode 方法,基于子类没有实例变量但从其超类继承 2 个实例变量的事实是否可能?

use*_*300 5

这实际上提出了一个难题。假设您有一个 Foo 类和两个子类 FooA 和 FooB。在您的应用程序/域中, FooA 等于 Foo 或 FooB是否有意义?

如果是这样,您应该在超类中实现 equals。并测试instanceof Foo. 基本上,在 FooA 或 FooB 中添加的任何额外字段都将被忽略。通常这是正确的。代码如下:

public boolean equals(Object o) {  // perfectionists will make this final
  if (this == o)
     return true;
  if (o instanceof Foo) {  // note that Foo, FooA and FooB would all pass
     Foo oFoo = (Foo)o;
     // compare all the fields of Foo here
  }

  return false;
}
Run Code Online (Sandbox Code Playgroud)

如果没有,则需要在子类中实现 equals。并测试类是否相等,而不仅仅是instanceof。例如

public boolean equals(Object o) {
  if (this == o)
     return true;
  if (o == null)  // this extra check is needed to avoid a NPE
    return false;
  if (o.getClass() == this.getClass()) {  // must be an exact match
     FooA oFoo = (FooA)o;
     // compare all the fields here
  }

  return false;
}
Run Code Online (Sandbox Code Playgroud)

一般来说,我认为大多数人都使用第一种方法。这似乎最适合您的问题。请参阅Josh Bloch 所著的《Effective Java》 。您会发现很多关于此的帖子,例如, 在生成 .equals() 时,有什么理由更喜欢 getClass() 而不是 instanceof?