This is due to how Java implements covariant return types. java.time.LocalTime
has a minus
method with signature
LocalTime minus(TemporalAmount amountToSubtract)
but this method implements an interface method from java.time.temporal.Temporal
with signature
Temporal minus(TemporalAmount amount)
This is permitted due to covariant return typing, but due to the way method lookup works, a lookup at runtime for the method that returns a Temporal
won't find the method that returns a LocalTime
. Thus, the compiler creates an ordinarily-forbidden method with the same signature, but returning a Temporal
. This method calls the version that returns a LocalTime
. At runtime, calls that want a Temporal
return type find the bridge method, and everything works out.
This bridge method is normally invisible, but it shows up in the javap
output, leading to your current confusion.
Source: http://www.artima.com/weblogs/viewpost.jsp?thread=354443
Here's the javap -c
disassembly for one of the bridge methods from StringBuilder
, showing how it calls the method with the same signature, but a more specific return type:
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