【问题标题】:Would overriding equals() with multiple instanceof tests be feasible for different objects?对于不同的对象,使用多个 instanceof 测试覆盖 equals() 是否可行?
【发布时间】:2011-10-28 09:12:46
【问题描述】:

假设我有一个类,我必须检查多种不同类型的对象。以下列方式覆盖equals() 是否可行/可能?

public boolean equals(Object o){
    if(o == null) return false;
    if(o instanceof class1){
        return this.class1.equals((class1) o);
    if(o instanceof class2){
        return this.class2.equals((class2) o);
    ...

}

这会有用吗?我在这里假设我在各自的类中创建了一个静态重载的equals() 方法(尽管只要我强制转换,多态性可能会自动处理这个问题?)。

【问题讨论】:

  • 它可能是“有用的”,这取决于你在做什么,但你必须知道在顶部有 equalshashCode Java 的层次结构纯粹是有缺陷的。没有办法解决它。一旦您拥有继承权,您就不能保证等于/哈希码合同。就如此容易。 不可能。 Joshua Bloch 在Effective Java 中很好地、非常清楚且无可争议地解释了这一点。在 Artima 上,Martin Odersky(来自 Scala 的名声)也就此主题发表了精彩的演讲。
  • 该代码是合法的,因此是可能的。但是,如果两个对象属于同一类,则说它们相等并不是一个好主意。如果你决心实现这样的实验,那么在 OO 中正确的做法是在每个子类中重写 equals。
  • 感谢你们伟大的 cmets。
  • @CedricMartin 不是真的,你可以。您只是不能将属性添加到更改相等性的子类。好吧,甚至前面的句子也是错误的:即使那样,您也可以正确实现等于(即不违反等式关系的任何保证数学属性),但通常不是任何人想要的 - 所以它几乎没有实用价值。实际上 odersky 写了一篇文章来展示如何做到这一点。编辑:或者你只是说你不能保证子类正确实现它?没错,但我想说的很多事情也是如此。
  • @Voo:Odersky 写了一篇文章,显示有一天可以解决这个问题,不使用 equals() 和 hashCode()(他正在创建其他方法)。 Joshua Bloch 说:“根本没有办法扩展一个可实例化的类并添加一个方面,同时保留 equals 契约”。所以我坚持我的断言,如果你想使用继承(是的,这通常意味着拥有类和子类),那么 equalshashCode 在 OO 层次结构的顶部在 Java 中被破坏了。我不认为有解决方法:我只是声明 equalshashCode 不应该存在。

标签: java equals instanceof


【解决方案1】:

我非常怀疑,因为您可以通过这种方式轻松违反 equals 的传递性(x.equals(y) && x.equals(z) 暗示 y.equals(z)

当然,除非你做了一个涉及所有类的非常全面的设置,但要正确设置会很痛苦

【讨论】:

  • 太糟糕了,我不能选择多个答案!
【解决方案2】:

您似乎想要一种方法来检查指定对象是否等于接收器中的各种成员变量中的至少一个。

为此目的覆盖java.lang.Object#equals 是不合适的。

您应该提供不同的方法,例如

public boolean hasEquals(Object o) { // your impl }

【讨论】:

    【解决方案3】:

    从语义上讲,我认为这不是一个好主意。等于不应该基于类类型,而是基于实例变量。 除此之外,苹果永远不应该等于梨,而只能等于其他苹果。

    【讨论】:

      【解决方案4】:

      如果您确定它不会导致相互递归,您可以返回that.equals(this)。然而,一般来说,对象相等意味着类的相等,或者至少它们之间存在一致的继承关系。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-07-08
        • 1970-01-01
        • 2011-09-25
        • 1970-01-01
        • 2010-11-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多