2

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);

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

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

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

4

3 回答 3

7

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

LocalTime minus(TemporalAmount amountToSubtract)

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

Temporal minus(TemporalAmount amount)

由于协变返回类型,这是允许的,但由于方法查找的工作方式,在运行时查找返回 aTemporal的方法不会找到返回 a 的方法LocalTime。因此,编译器创建了一个具有相同签名的通常禁止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       
于 2016-07-21T05:23:26.200 回答
2

Java 禁止在同一个类或接口中使用相同名称和签名的两个方法

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

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

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

于 2016-07-21T04:58:55.970 回答
0

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

javap java.time.LocalTime

于 2016-07-21T05:12:48.177 回答