编辑
我做的很差,给任何人提供了不完整的信息来确定我的问题的原因。真正的问题是我在 Animal 中有一个嵌套类,它有自己的 .equals,在其外部类型上调用 .equals。 (因此调用 .equals on animal 从嵌套类的 .equals 调用 .equals on animal)。
我在继承树中有三个类。假设它们是 Animal
--> Dog<Owner>
--> DogWithHumanOwner
.
所以 DogWithHumanOwner 是通用 Dog 的一个实现,它的主人专门有一个 Human。
我已经覆盖了 Animal 和 Dog 的 .equal 方法。 Dog 的 .equal 方法如下所示:
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!super.equals(obj))
return false;
[other stuff]
return true;
}
不过我实际使用的是 DogWithHumanOwner。似乎当我尝试比较两个 DogWithHumanOwner 的相等性时,dogWithHumanOwner 继承了 Dog<Owner>
中的 equals 方法。 ,它调用 super.equals,这是 dogWithHumanOwner 的父类(super class)的 .equals 方法,这是它所在的方法,因此它会导致递归循环和计算器溢出。
(我不需要比较 Dog<Owner>
类的实现的任何特定属性,因为我在 Dog<Owner>
中这样做并且所有者需要有适当的 equals 方法。)
编写 .equals 方法以避免此问题的最佳做法是什么?我在画一个空白。我是否应该完全不调用 super 而手动测试相等性?
编辑:我不得不删除 BlackLabs,因为我想用 blackLabs 做这件事没有意义。
最佳答案
编辑后编辑:
简而言之,是的,根本不要调用 super.equals
。此外,请确保 super.equals
使用类相等性而不是 instanceof
检查其传入对象的类。这就是 Object.equals
默认情况下所做的,所以如果 Animal
没有声明一个 equals
,你很好。
不过,我的其余回答仍然是相关的,因为以上基本上是对上一段结论的总结,就像之前一样。基本上,如果父类(super class)不需要等于子类的实例,那么每个人都可以检查对象是否相等(不是 instanceof
)以及他们想要的任何状态。如果父类(super class)只检查 instanceof
(不是更严格的相等性),那么基本上子类不能检查父类(super class)检查之外的任何额外状态。
在您的例子中,Animal 不检查任何东西,而 Dog 会。所以你可以开始了。
原回答如下:
如果 (a) 它们在某些特定的 BlackLab 品质上相等,并且 (b) 它们在 Dogness 上相等,您是否认为两个 BlackLab 相等?如果是这样,这是一个坏主意!它打破了 Object.equals 指定的相等的传递属性.想象一下你有:
- 黑实验室
- 黑实验室
- 狗c
假设这三个人的“狗性”相同,例如他们的体重、高度和名字。但这两个 BlackLab 的 BlackLabness 并不相同,例如它们外套的光泽。现在你有:
- a = c
- b = c
- a != b//打破传递性!
另一方面,如果 BlackLab.equals
没有添加任何额外的检查——那么您根本不需要覆盖它。它只会继承 Dog 的平等性,这就是您想要的。
正如 Mattias Buelens 指出的,您可以通过更严格的类型检查来解决这个问题——要求两个对象属于同一类,而不是使用 instanceof
。这修复了平等契约,但代价是体重 80 磅的 BlackLab“Rex”不等于体重 80 磅的名为“Rex”的未指定品种的狗。如果您考虑所需的特定用例,您可能会发现这是完全可以接受的。
关于java - 调用 super.equals 的递归 .equals 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16366797/