Java getClass和超类

时间:2015-06-29 16:30:57

标签: java superclass

public boolean equals(Object o) {
    if (this == o)
        return true;
    if ((o == null) || (this.getClass() != o.getClass()))
        return false;
    else {
        AlunoTE umAluno = (AlunoTE) o;
        return(this.nomeEmpresa.equals(umAluno.getNomeEmpresa()) && super.equals(umAluno);
    }
}

当论证是超类时,有人能解释第四行((this.getClass() != o.getClass()))是如何工作的吗?因为这些类有不同的名称。 this.getClass会返回与o.getClass不同的名称,对吗?

3 个答案:

答案 0 :(得分:0)

所以我们说有两个类。 A类和B类.A类是B类的超类。因此该方法将在B类中。" this.getClass()"引用类B的对象,而o.getClass()(超类)将引用类A.因此类B将不等于类A.意味着它将进入if语句。

答案 1 :(得分:0)

检查以下代码片段,以回答您的问题。对象O可以包含任何对象。 o.getClass()将返回对象的运行时类

public class Main {
  void method(Object o) {
    System.out.println(this.getClass() == o.getClass());
  }

  public static void main(String[] args) {
    new Main().method(new Object());  // false
    new Main().method(new Main());    // true
    new Main().method(new String());  // false
    new Main().method(new MainOne()); // false
  }
}

class MainOne extends Main
{
}

答案 2 :(得分:0)

假设您的超类是SHAPE,并且您有一个类RECT,它是SHAPE的子类。 如果此变量用于RECT,而对象o也是RECT, 然后第4行将返回true,因为它们是同一个类(RECT)。 只要它们的类型在运行时相同,这两个对象就是相同的。

但是,如果Object o的类型为SQUARE,它也是SHAPE的子类, (甚至可以继承RECT)。 那么它不会等于这个指针(RECT), 因为他们的课程在运行时是不同的。

现在为什么这种类型检查在equals方法中是坏的(特别是对于 Hibernate 实体类的用例)。

如果您使用Hibernate,并且在Hibernate中缓存时,您正在检查一个新创建的对象,其类类型为RECT,而该类对象的类类型为RECT,则缓存中对象的类实际上将是一个子类 - 类型为RECT的类,因为Hibernate执行字节码操作并将对象包装在合成子类(RECT _ $$ javassist)中。

这意味着您期望相等的Hibernate缓存对象永远不会相等。

如果对象在子集合中,Hibernate将假定您要从集合中删除旧对象并在集合中创建新对象,而不是对集合中的现有对象执行(潜在)更新。 我们有遗留代码执行此操作,并且永远无法弄清楚为什么(直到现在)它一直在删除并重新插入我们的集合。

对于Hibernate实体对象,您应该使用instanceof运算符来确定两个对象是否相等 - 然后转换Object o并继续使用类SHAPE特定字段进行比较操作。

如果你的子类不应该被认为是相等的,那么你必须在每个子类中实现equals()来检查instanceof。

对于其他用例,您必须确定某人(或其他某些库)是否可能对您的类进行子类化(即使通过字节代码操作)以及是否仍应将任何子类视为相等或不。

例如,如果你在单元测试中做了任何类型的模拟,那么一个错误的equals方法可能会导致其他相等的对象由于它们的类不相等而不相等。

回到OP的代码。编码equals方法的更好方法是:

public boolean equals(Object o) {
    if (this == o)
        return true;
    if (!(o instanceof AlunoTE))
        return false;
    AlunoTE umAluno = (AlunoTE) o;
    return(this.nomeEmpresa.equals(umAluno.getNomeEmpresa()) && super.equals(umAluno);
}

因为instanceof运算符总是为null返回false,所以也不需要进行空检查。