Java 类有 2 个函数签名相同但返回类型不同的方法

标签 java overloading javap

据我所知,不可能有一个具有相同调用签名的方法。然而:

$ javap -public java.time.LocalTime  | grep "minus" | grep "Temporal" | grep -v "long"
    public java.time.LocalTime minus(java.time.temporal.TemporalAmount);
    public java.time.temporal.Temporal minus(java.time.temporal.TemporalAmount);

这些清楚地显示了具有相同调用签名的多个方法。

  1. Java 如何解析函数调用?
  2. 为什么会有多个函数?

编辑:通过仅保留相关位来简化问题。

最佳答案

这是由于 Java 如何实现协变返回类型。 java.time.LocalTime 有一个带签名的minus 方法

LocalTime minus(TemporalAmount amountToSubtract)

但是这个方法实现了一个来自 java.time.temporal.Temporal 的带有签名的接口(interface)方法

Temporal minus(TemporalAmount amount)

由于协变返回类型,这是允许的,但由于方法查找的工作方式,在运行时查找返回 Temporal 的方法将找不到返回 的方法>本地时间。因此,编译器创建了一个具有相同签名但返回 Temporalordinarily-forbidden 方法。此方法调用返回 LocalTime 的版本。在运行时,需要 Temporal 返回类型的调用会找到桥接方法,然后一切正常。

这个桥接方法通常是不可见的,但它出现在 javap 输出中,导致您目前的困惑。

来源:http://www.artima.com/weblogs/viewpost.jsp?thread=354443

下面是 StringBuilder 中桥接方法之一的 javap -c 反汇编,展示了它如何调用具有相同签名但返回类型更具体的方法:

  public java.lang.Appendable append(java.lang.CharSequence) throws java.io.IOException;
    Code:
       0: aload_0       
       1: aload_1       
       2: invokevirtual #6                  // Method append:(Ljava/lang/CharSequence;)Ljava/lang/StringBuilder;
       5: areturn       

关于Java 类有 2 个函数签名相同但返回类型不同的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38495153/

相关文章:

java - 如何获取接口(interface)内部方法的签名?

java - 静态代码块有什么用?

c++ - 强制特定类型的函数模板/函数重载

java - Java 安全模块 KeyGenerator 线程安全吗?如果不是那么如何解决?

java - 在 Jetty servlet 中处理 uri 参数

java - Apache CXF 3.1.6 Web 服务客户端 - NTLM 身份验证

java - Java虚拟机是否允许返回类型重载?

module - Racket /计划中的运算符重载

java javap和groovy字节码比较

java - 我想动态更新 gui.properties 文件的键值对