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

Java class has 2 methods with the same function signature but different return types

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

$ 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 forbids two methods in the same class or interface with the same name and signature.

但是,两个不同的 classes、接口或枚举可以具有相同的方法签名;例如,这是有效的:

public java.time.LocalTime minus(long, java.time.temporal.TemporalUnit);
public java.time.temporal.Temporal minus(long, java.time.temporal.TemporalUnit);

一个minus方法属于LocalTimeclass,另一个属于Temporal接口。由于 LocalTime implements Temporal,两者之间 必须 签名匹配,否则合同未履行,这将导致编译错误。

Temporal 是由 LocalTime 实现的接口,因此它们的方法具有相同的签名 如果你想检查试试这个

javap java.time.LocalTime

这是由于 Java 如何实现协变 return 类型。 java.time.LocalTime 有一个带有签名

minus 方法
LocalTime minus(TemporalAmount amountToSubtract)

但此方法实现了来自 java.time.temporal.Temporal 的接口方法,带有签名

Temporal minus(TemporalAmount amount)

由于协变 return 键入,这是允许的,但由于方法查找的工作方式,在运行时查找 return 是 Temporal 的方法将找不到return 是 LocalTime 的方法。因此,编译器创建了一个 通常禁止的 具有相同签名的方法,但 returning 了 Temporal。此方法调用 return 为 LocalTime 的版本。在运行时,需要 Temporal return 类型的调用找到桥接方法,一切正常。

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

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

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

  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