2

我已经定义了两个类:Employee 和 Doctor,他们是父子。像这样的代码:

class Employee {
  // ....
}

class Doctor extends Employee {
  // ....
}

然后我写了一个这样的主要方法:

public static void main(String[] args) {
        Doctor doctor = new Doctor();
        Employee employee = new Employee();
        System.out.println(doctor.getClass() == new Employee().getClass());  // code 1
        System.out.println(employee.getClass() == Employee.class);  // code 2
        System.out.println(doctor.getClass() == Employee.class); // code 3
    }

但只有code 1andcode 2 是正确的并code 3调用异常:

Error:(33, 46) Java: uncomparable type: java.lang.Class<capture#1 extends Doctor> and java.lang.Class<Employee>

我知道我可以用它equals来处理这个问题,但我想知道为什么我不能用运算符==来比较它们。

4

1 回答 1

1

您观察到的行为是正确的,但要解释原因,我们需要参考 Java 语言规范。

§15.8.2。类文字

的类型C.class,其中C是类、接口或数组类型(第 4.3 节)的名称,是Class<C>

§4.3.2。班级Object说:

的方法调用表达式的类型getClassClass<? extends |T|>,其中T是搜索的类或接口getClass(第 15.12.1 节)并|T|表示(第 4.6 节)的擦除T

§15.21.3。参考相等运算符==!=说:

如果无法通过强制转换(第 5.5 节)将任一操作数的类型转换为另一个操作数的类型,则会出现编译时错误。两个操作数的运行时值必然不相等(忽略两个值都是 的情况null)。

因此,我们可以写下每个表达式的编译时类型:

  • Employee.class是类型Class<Employee>
  • Doctor.class是类型Class<Doctor>
  • employee.getClass()并且new Employee().getClass()都是 type Class<? extends Employee>。这意味着Class代表它的一个Employee或一个子类,包括Doctor.
  • doctor.getClass()并且new Doctor().getClass()都是 type Class<? extends Doctor>。这意味着Class代表它的一个Doctor或一个子类,例如Surgeon也许。

现在我们可以解释所有三种行为:

  1. doctor.getClass() == new Employee().getClass()比较 aClass<? extends Doctor>Class<? extends Employee>。第一种类型可以通过强制转换转换为第二种类型,因此这是允许的。
  2. employee.getClass() == Employee.class将 aClass<? extends Employee>与 a进行比较Class<Employee>。第二种类型可以通过强制转换转换为第一种类型,因此这是允许的。
  3. doctor.getClass() == Employee.class将 aClass<? extends Doctor>与 a进行比较Class<Employee>。两种类型都不能通过强制转换转换为另一种类型,因此这是编译时错误(不是异常)。

更详细地介绍 3.,aClass<? extends Doctor>可以满足Class<Doctor>or Class<Surgeon>,但不能满足,Class<Employee>因为Employee不是 的子类型Doctor。但是,如果您doctor在调用之前向上转换,则可以编写一个具有预期结果的类似表达式getClass

  1. ((Employee) doctor).getClass() == Employee.class与情况2类似,所以是允许的。

诚然,通过向上转换而不是向下转换来修复类型错误是非常不寻常的。

于 2020-02-23T12:15:31.480 回答