【问题标题】:Why to cast a class to be compared before overriding equals()?为什么要在覆盖 equals() 之前强制转换一个要比较的类?
【发布时间】:2014-11-04 10:42:32
【问题描述】:

那么在下面的代码段中,为什么我们还要显式地强制转换“其他”类,即使它已经通过了 getClass() 结果的相等性测试。

public boolean equals(Object other) {
.
.
.
if (getClass() != other.getClass()) return false;

Person person = (Person)other;
.
.
.
}

【问题讨论】:

  • 这样你就可以访问该类的成员了。
  • 如果您将Object 视为Person 而不进行显式转换,编译器会报错。例如,如果你使用 other.firstName,你会失败,但假设 Person 类有该成员,使用 person.firstName 就可以了。

标签: casting equality


【解决方案1】:

为了让代码能够访问Person 对象中的任何方法或字段,必须进行强制转换。

public boolean equals(Object other){

   if( !(other instanceof Person)){
       return false;
   }

   Person otherPerson = (Person)other;

   //now we can check equality
   return getLastname().equals(otherPerson.getLastname() )
        && getFirstname().equals(otherPerson.getFirstname() );
}

编辑 如果要检查对象不是直接子类的相等性,还可以使用instanceof 来测试对象是否实现和接口。例如List接口是ArrayListVectorLinkedList的父对象。如果您想测试两个对象的相等性,其中它们的类型是其中任何一个,您可以通过检查这两个对象是否实现 List 并且它们的元素都相等且顺序相同。

这是来自AbstractList 的代码,它就是这样做的。请注意,我们必须强制转换为一个列表才能在另一个对象上调用 listIterator() 方法:

 public boolean equals(Object o) {
    if (o == this)
        return true;
    if (!(o instanceof List))
        return false;

    ListIterator<E> e1 = listIterator();
    ListIterator<?> e2 = ((List<?>) o).listIterator();
    while (e1.hasNext() && e2.hasNext()) {
        E o1 = e1.next();
        Object o2 = e2.next();
        if (!(o1==null ? o2==null : o1.equals(o2)))
            return false;
    }
    //this check will return false if either iterator
    //still has elements left which means the lists aren't the same size. 
    return !(e1.hasNext() || e2.hasNext());
}

【讨论】:

  • 谢谢先生。这是否意味着我们不能比较来自两个不同树的两个类的对象?我的意思是如果一个类不是另一个类的子类...
【解决方案2】:

您现在可以在进行比较时使用person.getterOnPerson()。回想一下,Object 类不包含检索所需值的所有必要方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-05-10
    • 2013-06-03
    • 1970-01-01
    • 2016-02-02
    • 2011-10-30
    • 2013-07-05
    • 2021-05-08
    • 1970-01-01
    相关资源
    最近更新 更多