在 Java 中覆盖等于 - 对实现感到困惑

Overriding Equals in Java - confused about implementation

我一直在学习 MOOC Java 编程课程,他们通常会这样重写 equals:

  1. 如果 2 个对象的地址相同 = return true.
  2. 如果比较的对象不是与第一个对象相同的 class 的实例 = return false。
  3. 将对象转换为与比较对象相同的类型
  4. 比较每个对象的变量 - returns true or false

我对第 2 步和第 3 步有点困惑。


如果不是,该方法将忽略其余代码并且 returns false

如果是,我们将其转换为 Class。 所以在这一点上我很困惑为什么我们需要将一个已经是相同 class 的实例的对象转换为那个 class? 如果 Java承认是同类型,为什么要转换呢?

*示例如下:

public boolean equals(Object comparedObject) { 
// if the variables are located in the same place, they're the same 
  if (this == comparedObject) { 
    return true; 
  }

// if comparedObject is not of type Book, the objects aren't the same **   
  if (!(comparedObject instanceof Book)) { 
    return false; 
  }
// convert the object to a Book object
Book comparedBook = (Book) comparedObject;**

// if the instance variables of the objects are the same, so are the objects
  if (this.name.equals(comparedBook.name) &&
    this.published == comparedBook.published &&
    this.content.equals(comparedBook.content)) {
    return true;
}

// otherwise, the objects aren't the same
return false;
}

因为你只比较了动态类型; comparedObjectstatic 类型没有改变:它是 Object,你不能访问它的 Book 成员(想一想:此时 you 知道 comparedObject 的动态类型是 Book;但是 Java 编译器仍然看到它及其声明的类型)。要让编译器明白对象类型是Book,首先需要创建一个static类型是[=12的对象=],为此你需要演员表。

静态类型信息是Java 编译器看到的,也是编译器用来检查你的代码是否静态正确的信息。

Java 是静态类型的,所以如果变量被声明为 Object 它不会让你访问任何字段或调用 Book 的任何方法。在这种情况下,很容易证明该对象只能是 Book,但编译器不会尝试证明它。 (而且,在 中,它不能。)

在 Java 的最新版本中,您可以使用以下语法的快捷方式:

if (comparedObject instanceof Book book) {
    // do whatever with book
    return this.title.equals(book.title) && this.author.equals(book.author);
}

但在早期版本中,您只需向下转换实例即可:

if (comparedObject instanceof Book) {
    Book book = (Book) comparedObject;
    return this.title.equals(book.title) && this.author.equals(book.author);
}