覆盖包含重写的equals()的类的子类中的equals()

时间:2012-02-06 06:50:03

标签: java equals

我有一个Point类和一个MinesweeperSquare类,后者是前者的子类。如果我覆盖后者中的equals方法,就像这样:

if (!(obj instanceof MinesweeperSquare)) {
  return false;
}

FindBugs报告:

  

此类定义一个equals方法,该方法覆盖超类中的equals方法。两者都等于方法   方法使用instanceof来确定两个对象是否相等。这充满了危险,   因为重要的是equals方法是对称的(换句话说,a.equals(b) == b.equals(a))。   如果B是A的子类型,并且A的equals方法检查参数是A的实例,B的等于方法   检查参数是B的实例,很可能是由这些定义的等价关系   方法不对称。

Point课程中,我写道:

if (!(obj instanceof Point)) {
  return false;
}

如何在equals中编写MinesweeperSquare方法,使equals方法对称?

更新

如果我在MinesweeperSquare中写下以下内容,则FindBugs报告没有错误:

if (o == null || this.getClass() != o.getClass()) {
  return false;
}

3 个答案:

答案 0 :(得分:3)

在您的新方法中,MinesweeperSquare.equals(Point)将始终返回false,但Point.equals(MinesweeperSquare)可能会返回true。在这种事情上使用FindBugs对你很好。您可以在getClass()Point的定义中使用MinesweeperSquare来检查类是否完全相同......尽管这也很棘手。

答案 1 :(得分:1)

正如您已经引用过的,如果在equals()方法实现中使用'instanceof'运算符,它将变为非对称运算符。摆脱超类中的'instanceof'以及所有子类,并尝试根据类属性和常识覆盖equals()方法。大多数IDE允许您自动生成equals()方法,这是一个很好的起点。

答案 2 :(得分:1)

如果正确完成,使用instanceof就没问题,如果没有正确的讲座,这很难。使用

this.getClass().equals(that.getClass())

是微不足道的,但并不总能满足您的需求。查看canEqual的{​​{3}}。

修改

这一切都只适用于你控制这两个类的情况,这在这里似乎并非如此。所以坚持使用简单的方法。