Java equals方法的实现模式错误

时间:2014-01-28 14:39:17

标签: java subclass equals

我已经看到了java equals()方法的许多实现,它们遵循以下几行:

public boolean equals(Object other){
    if (this == other) 
        return true;

    //this if code
    if (!(other intanceof MyClass))
        return false;
    //ends here

    otherMyClass = (MyClass)other;
    //check all the attribute of this and otherMyClass and return true or false
    //accordingly
}

在o1.equals(o2)(对于MyClass的o1对象和MyClasss的子类的o2对象)中它将返回true的意义上是不是代码有问题?在大多数情况下,这不是预期的行为。

other.getClass() != this.getClass()不是一个更好的比较而不是上面的粗体吗?

4 个答案:

答案 0 :(得分:2)

o.getClass() != getClass())违反Liskov替代原则。

引用一位伟人:

  

Liskov替代原则说任何重要的财产   一个类型也应该为其子类型保留,以便编写任何方法   对于该类型应该在其子类型上同样有效。

本书Effective Java有关于此主题的更多详细信息。

答案 1 :(得分:0)

如果

if (!(other intanceof MyClass)) return false是不同类的实例,则返回false。

我无法遵循关于返回true的逻辑,因为它无法返回true。它可以评估为true,在这种情况下会执行下一个语句。

答案 2 :(得分:0)

我认为@ChrisForrence(+1)在评论中引用了最佳答案:Any reason to prefer getClass() over instanceof when generating .equals()?

我想提醒您注意使用instanceof使equals()实现不对称:如果A是基类而B扩展A而不定义任何其他字段或方法,则可以{ {1}} a.equals(b) == true其中b.equals(a) == falsea的实例,Ab的实例。

答案 3 :(得分:0)

我在一年前的一次采访中确实遇到过这个问题。我的实现也是使用instanceof。我的面试官提到了使用getClass()== other.getClass()的两个论点:

  • 你可能永远不需要在任何实际情况下的子类实例等于父对象; equals方法最常见的用途是集合(更具体地说是集合);我在实践中从未遇到过这种情况,但如果有人在这里做过,请随意添加任何非纯理论情况作为评论仍然适用(老实说,如果有这样的情况,我很好奇)
  • 请记住等号合约(JavaDoc for Object)的属性:
    • 自反
    • 对称(*)
    • 传递
    • 一致的
    • x.equals(null)为任何对象x返回false
      • 这已经在其他答案中指出:对称性属性可能与instanceof有问题(再次,在实践中,我很少使用包含不同类型元素的集合,但每当我有不同的类型时,我从一开始就知道对象实际上是不同的)