【问题标题】:We can override method by changing return type (Covariant Return Type) in Java. Why? [duplicate]我们可以通过更改 Java 中的返回类型(协变返回类型)来覆盖方法。为什么? [复制]
【发布时间】:2020-04-14 11:14:46
【问题描述】:

Java 中不能通过改变返回类型来重载方法,但是我们可以通过改变返回类型(协变返回类型)来覆盖方法。 为什么

更具体地说,JVM 使用方法的完整签名进行查找/解析。完整签名意味着它除了参数类型之外还包括返回类型。即,一个类可以有两个或多个方法,仅在返回类型上有所不同。 javac 使用这个事实来实现协变返回类型。

那么为什么我们不能重载使用协变返回类型的方法呢?

【问题讨论】:

  • 对于您关于重载的问题,我相信 Java 解释器只“看到”方法名称和参数的数量/类型,而不是返回类型。因此,只有返回类型不同的两个具有相同签名的方法看起来是一样的。对于您问题的后半部分,不能随意更改覆盖的返回类型。它要么必须匹配接口中的类型比该类型更具体。
  • @ElliottFrisch JLS 不要求使用基于堆栈的虚拟机。 JVMS 确实如此。
  • 为什么——如果Java不允许被覆盖的方法使用协变返回类型,那么这会损害继承特性,我认为这就是设计人员可能会这样想的原因。跨度>
  • @TimBiegeleisen JVM 使用方法的完整签名进行查找/解析,为什么它无法区分具有不同返回类型的两种方法。
  • 我的理解可能是错误的,但是我的理解是JVM去调用一个方法时,它只能通过参数的名称和数量/类型来确定调用哪个版本。如果只是两种方法的返回类型不同,JVM 就无法确定调用哪个版本。

标签: java oop


【解决方案1】:

答案可能听起来很幼稚,但我认为如果您不使用函数调用的返回值,这样做会使编译器混淆您尝试使用哪个函数。

int foo(int a, int b) {...}

double foo(int a, int b) {...}

// calling one of the function and not using return value
foo(3,4);

编译器在生成类文件时,在编译文件中具有完整的方法签名(包括返回类型和包名),以唯一标识确切的函数。如果允许使用不同的返回类型进行重载,则编译器会在决定使用哪个函数时感到困惑,前提是您没有使用返回值。

【讨论】:

    猜你喜欢
    • 2021-11-16
    • 1970-01-01
    • 2011-09-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-27
    • 2015-04-01
    相关资源
    最近更新 更多