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);
这些清楚地显示了具有相同调用签名的多个方法。
- Java如何解析函数调用?
- 为什么会有多个函数?
编辑:通过仅保留相关位来简化问题。
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
方法属于LocalTime
class,另一个属于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
据我所知,不可能有一个具有相同调用签名的方法。然而:
$ 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);
这些清楚地显示了具有相同调用签名的多个方法。
- Java如何解析函数调用?
- 为什么会有多个函数?
编辑:通过仅保留相关位来简化问题。
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
方法属于LocalTime
class,另一个属于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