一尘不染

Java有什么理由在生成.equals()时更喜欢getClass()而不是instanceof?

java

我正在使用Eclipse生成.equals().hashCode(),并且有一个标记为“使用'instanceof'比较类型”的选项。缺省是不选中此选项并用于.getClass()比较类型。有什么我.getClass()比我更喜欢的理由instanceof吗?

不使用instanceof

if (obj == null)
  return false;
if (getClass() != obj.getClass())
  return false;

使用instanceof

if (obj == null)
  return false;
if (!(obj instanceof MyClass))
  return false;

我通常会选中该instanceof选项,然后去掉“ if (obj == null)”检查。(这是多余的,因为空对象将始终失败instanceof。)是否有任何不好的主意?


阅读 413

收藏
2020-03-07

共2个答案

一尘不染

如果你使用instanceof,让你equals实现final将保留方法的对称性合同:x.equals(y) == y.equals(x)。如果final看似有限制,请仔细检查你的对象等效性概念,以确保你的首要实现完全维护Object类所建立的契约。

2020-03-07
一尘不染

Josh Bloch支持你的方法:

我赞成instanceof使用该getClass方法的原因是,当使用该方法时,存在一些限制,即对象只能与相同类,相同运行时类型的其他对象相等。如果你扩展了一个类并为其添加了一些无害的方法,那么检查一下子类的某个对象是否等于超类的一个对象,即使这些对象在所有重要方面都相等,你也会得到他们不平等的令人惊讶的答案。实际上,这违反了对Liskov替换原理的严格解释,并可能导致非常令人惊讶的行为。在Java中,它特别重要,因为大多数集合(HashTable等)基于equals方法。如果将父类的成员放在哈希表中作为键,然后使用子类实例进行查找,则找不到它们,因为它们不相等。

2020-03-07