编译器如何识别 return 类型的覆盖方法在 Java 中不兼容?

How does the compiler identify that the return types of overridden methods are incompatible in Java?

这听起来像是一个重复的问题,但我真的很好奇编译器如何识别被覆盖的方法和被覆盖的方法是否具有兼容的类型。我们知道通常方法是使用它们的签名来标识的,并且签名只包含方法名称及其参数,因此在重载时它可以很容易地找出要选择哪个方法,因此我们不能在重载时有两个完全相似的方法.但是为了重写,我们需要两个方法完全相同。那么编译器如何判断return类型是否兼容呢?

编辑。我很清楚要执行的方法是根据程序运行时的引用来选择的,我只是好奇编译器的识别是如何工作的。

由于这是一个没有实现Java编译器的社区,我们所能做的就是推测,但是尽管如此,推测一下,只要客观地进行,可能会成为一本好书.

所以,我的回答将集中在如何验证方法 上,因为我不知道编译器实际上是如何完成的。

首先,一个很简单的检查是参数个数是否相同。此外,参数的类型和方法的 return 类型必须相同才能完全覆盖方法。

我应该提一下,如果在子 class 中实现了方法的新签名,那不是问题,完全合法。

所以,

class A {
    int foo(long a) { return 0;}
}

class B extends A {
    int foo(long a) { return 0;}
}

class C extends A {
    int foo(double a) { return 0;}
}

完全合法。

因此,确定一个方法是否重写另一个方法对于 Java 了解如何应用基于继承的逻辑很重要,但是您可以轻松地实现具有不同声明的方法,但是,同名。

编译器识别覆盖方法的条件是

  • 方法必须具有相同的签名
  • 方法必须至少与父方法一样可访问
  • 方法必须使用协变return类型
  • 方法不得声明任何新的或更广泛的异常

如 OCP II 学习指南中所述。

如果方法名称相同但参数列表不同,则方法被重载。