在Java中使用.compareTo()时如何使.equals()对称

时间:2016-07-04 11:08:24

标签: java sonarqube

这里有一个类似的问题(Implementing equals method using compareTo) - 最后建议重复使用.compareTo()来实施.equals(),只要不违反合同 - 我的重点是合同x.equals(y) == y.equals(x).equals()的简单实现将是/可能是

public boolean equals(Object obj) {
  return obj != null && (obj instanceof MyClass) && 0 == this.compareTo((MyClass)obj);
}

所以这是我的问题:当我有ParentClass以这种方式实现它时,以及ChildClass extends ParentClass,我会遇到ChildClass实例的问题也是ParentClass的一个实例,但反之亦然。

因此,parent的实例ParentClasschild的实例ChildClass至少可能 - 使用上面的.equals() - {{1} }}

那么如何使用child.equals(parent) != parent.equals(child)实现.equals()并保证.compareTo()

有什么想法吗?感谢。

编辑:这个问题的起源是SonarQube抱怨简单的实现不对称 - 上面的问题是我对SonarQube抱怨的解释。解决方案应该是对称的,但不应涉及太多变化。

4 个答案:

答案 0 :(得分:1)

仅使用instanceof进行平等检查从根本上说是不安全的。如果与子类的相等性没有意义,则需要使用this.getClass().equals(other.getClass())来比较类的相等性。如果您希望允许子类与父类相等(这在许多情况下无效),您必须检查关系并委托给子。父母不可能知道正确的平等定义。

class Parent {
  boolean equals(Object other) {
    if (! other instanceof Parent) return false
    if (! other.getClass().equals(Parent.class)) return other.equals(this);
    // Otherwise compare two objects that precisely have the type Parent
  }
}

请注意,如果孩子不是最终孩子,您还必须(适当地)与孩子一起做。在子等于,你可以允许另一个是Parent的实例(但你需要适当地比较相等)。

答案 1 :(得分:0)

您是否尝试覆盖子类中的equals方法以检查父类的obj?

答案 2 :(得分:0)

  

那么如何使用.equals()实现.compareTo()并保证child.equals(parent) == parent.equals(child)

检查两个不同对象的相等性似乎不正确。您可以创建一个接口,实现到parent,然后使用此接口检查子级和父级的相等性。

答案 3 :(得分:0)

所以,这是一个SonarQube(规则findbugs:EQ_UNUSUAL)满意的解决方案......

public boolean equals(Object obj)
{
    return obj != null && this.getClass().equals(obj.getClass()) && this.compareTo(obj) == 0;
}

至少这似乎是紧凑的,应该满足合同。