Java等于方法的良好设计

时间:2016-01-30 22:56:42

标签: java

我已经看到了这个:

// Returns whether o refers to a Point object with  
// the same (x, y) coordinates as this Point object 
public boolean equals(Object o) {
    if (o instanceof Point) {
        Point other = (Point) o;
        return x == other.x && y == other.y;
    } else {
        return false;
    } 
}

为什么要求equals方法的参数采用Point对象更为明智(并且更简单)。然后,如果我们尝试将Point与非Point进行比较,那么编译器将捕获它。那不是更好吗?

3 个答案:

答案 0 :(得分:4)

因为它不会覆盖Object.equals,这是许多标准库算法用于检查两个对象相等性的方法。

这些算法中的许多算法可以对不同类型的对象进行操作,因此equals可以将您的对象与任何其他类的对象进行比较。

答案 1 :(得分:1)

因为这会打破覆盖的第一条规则,并成为equals()

Object方法的重载

方法覆盖规则:

  • 参数列表应该与。的完全相同 重写方法。
  • 返回类型应与返回类型相同或为子类型 在超类中的原始重写方法中声明。
  • 访问级别不能比被覆盖的更严格 方法的访问级别。例如:如果超类方法是 声明公共然后子类中的重写方法不能 是私人的还是受保护的。
  • 实例方法只有在被实例继承时才能被覆盖 子类。
  • 无法覆盖声明为final的方法。
  • 声明为static的方法无法重写,但可以重新声明。
  • 如果某个方法无法继承,则无法覆盖该方法。
  • 与实例的超类相同的包中的子类可以 覆盖任何未声明为private或final的超类方法。
  • 不同包中的子类只能覆盖非final 声明为公共或受保护的方法。

答案 2 :(得分:-1)

您可以在Apache Commons库中简单地使用EqualsBuilder类。 https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/builder/EqualsBuilder.html

public boolean equals(Object obj) {
    if (obj == null) { return false; }
    if (obj == this) { return true; }
    if (obj.getClass() != getClass()) {
      return false;
    }
    MyClass rhs = (MyClass) obj;
    return new EqualsBuilder()
                  .appendSuper(super.equals(obj))
                  .append(field1, rhs.field1)
                  .append(field2, rhs.field2)
                  .append(field3, rhs.field3)
                  .isEquals();
}

将是

public boolean equals(Object obj) {
    return EqualsBuilder.reflectionEquals(this, obj);
}