理解有关Class的FindBugs警告不会覆盖超类中的equals

Gee*_*eek 3 java equals hashcode intellij-idea

根据Josh Bloch在Java中的说法:

除非您愿意放弃面向对象抽象的好处,否则无法扩展可实例化的类并在保留equals合同的同时添加值组件.

因此,这里是我的情况下,我有一类Foo是已经覆盖equals()hashcode()通过IntelliJ IDEA的实现.现在我有另一个类FooChild扩展Foo并为'Foo`增加了几个字段.现在FindBugs抱怨FooChild:

类不会覆盖超类中的equals此类扩展一个定义equals方法并添加字段的类,但不定义equals方法本身.因此,此类的实例上的相等性将忽略子类的标识和添加的字段.确保这是预期的,并且您不需要覆盖equals方法.即使您不需要重写equals方法,也可以考虑覆盖它,以便记录子类的equals方法只返回调用super.equals(o)的结果这一事实.

我的问题是" 这个类的实例上相等是什么意思会忽略子类的身份?我理解忽略添加字段的部分,因为还没有equals()为它们编写方法.

Ern*_*ill 5

"类的实例上的相等性将忽略子类的身份是什么意思?"

如果类Foo有一个equals()方法,那么FooChild继承它,这意味着如果比较两个FooChildusing 实例,将调用equals()Foo.equals()方法.

如果FooChild有任何数据成员,那么两个实例可能FooChild在其Foo部分中具有相同的成员值,但是直接在类中定义的成员的值不同.但是该Foo.equals()方法只会查看定义的成员Foo,因此equals()即使它们的FooChild部分不同,也会发出两个这样的对象.

这就是你需要覆盖equals()的原因FooChild.

现在,如果比较会发生什么FooFooChild使用equals(),当这两个类都有自己的版本equals()?它取决于您调用的对象equals(),它取决于您如何实现这两种equals()方法.坦白说,这太乱了!这就是第一句话的意思,即Josh Bloch的意思.定义这两种equals()方法是不可能的,因此它们总能做正确的事情.因此,最好避免一个值类(即,其标识与其成员变量的值绑定的类)扩展另一个值类的情况.

  • @Geek:调用库无法解决这个问题,因为它根植于Object.equals(Object)的契约中.使用组合而不是继承来确保您比较喜欢. (2认同)