小编典典

在此示例中,为什么即使在调用getClass()之后,也仍然必须对对象进行类型转换以确保其类型?

java

我正在使用Java上的OOP上的MOOC,它提供了一个我不完全理解的示例。在该示例中,Book已创建一个类,并且他们正在为Book该类构造“等于”重写方法。新equals()方法采用任何对象的参数。如果该参数是Book与该对象具有相同名称和PublishingYear
的对象,则返回true
Book。因为参数对象可以是Object类的任何对象,所以在调用getPublishingYear()getName()方法之前,如果在不在Book类中的对象上调用该对象,则会抛出错误,因此该equals()方法将检查以确保确实Book通过此代码处理对象:

 if (getClass() != object.getClass()) {
        return false;
 }

我非常了解(我认为)。我不明白的是,为什么在上面的代码之后,他们随后将参数对象转换为a
Book,然后在新转换的对象而不是原始对象上调用getPublishingYear()getName()

Book compared = (Book) object;

if (this.publishingYear != compared.getPublishingYear()) {
    return false;
}

if (this.name == null || !this.name.equals(compared.getName())) {
    return false;
}

    return true;

我不明白为什么如果由于上述getClass()检查该对象不是Book类型的方法应该已经返回false,则为什么必须执行此步骤。我尝试在没有此额外转换步骤的情况下进行编译,发现该步骤确实是必需的-
如果不包括此步骤getPublishingYear()getName()则编译器将显示“找不到符号”错误。那我想念什么呢?

equals()完整的方法:

@Override
public boolean equals(Object object) {
    if (object == null) {
        return false;
    }
    System.out.println(getClass());
    if (getClass() != object.getClass()) {
        return false;
    }

    Book compared = (Book) object;

    if (this.publishingYear != compared.getPublishingYear()) {
        return false;
    }

    if (this.name == null || !this.name.equals(compared.getName())) {
        return false;
    }

    return true;
}

阅读 183

收藏
2020-11-30

共1个答案

小编典典

将变量强制转换为数据类型基本上是告诉编译器“相信我,我知道我在做什么”。在将“对象”强制转换为“书”的情况下,您要确保编译器该对象实际上是一本书,并相应地进行操作。这也迫使您相信自己知道自己在做什么。

编辑:我不确定是否要问为什么需要实际的转换(添加“(Book)”)或为什么需要对Book变量进行赋值。我回答了前者。如果问题是后者,则答案是您需要Book变量,以便可以使用Book方法。

由于您拥有进行确定的工具,因此您会认为不需要进行强制转换,因为编译器能够生成用于确定的相同代码,只需执行赋值即可:

Book book = object;           // Wrong

代替

Book book = (Book) object;    // Right

如果希望编译器“仅知道”该对象是Book,则每次使用Book方法时,编译器都必须测试Object。通过在分配中明确告诉它,编译器可以创建特定于Book类的代码,而无需进一步检查Object。

2020-11-30