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

Sau*_*Das 2 java overloading javap

AFAIK不可能有一个具有相同呼叫签名的方法.然而:

$ 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);
Run Code Online (Sandbox Code Playgroud)

这些清楚地显示了具有相同呼叫签名的多种方法.

  1. Java如何解析函数调用?
  2. 为什么有多种功能?

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

use*_*ica 6

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

LocalTime minus(TemporalAmount amountToSubtract)
Run Code Online (Sandbox Code Playgroud)

但是这个方法实现了一个java.time.temporal.Temporal带签名的接口方法

Temporal minus(TemporalAmount amount)
Run Code Online (Sandbox Code Playgroud)

由于协变返回类型,这是允许的,但由于方法查找的工作方式,在运行时查找返回a Temporal的方法将找不到返回a的方法LocalTime.因此,编译器创建一个具有相同签名的普通禁止方法,但返回a Temporal.此方法调用返回的版本LocalTime.在运行时,想要Temporal返回类型的调用找到桥接方法,一切都解决了.

这种桥接方法通常是不可见的,但它会显示在javap输出中,从而导致您当前的混淆.

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

以下是javap -c其中一个桥接方法的反汇编StringBuilder,显示了它如何使用相同的签名调用该方法,但更具体的返回类型:

  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       
Run Code Online (Sandbox Code Playgroud)