これは、Java が共変の戻り値の型を実装する方法によるものです。署名付きjava.time.LocalTime
のメソッドがありますminus
LocalTime minus(TemporalAmount amountToSubtract)
java.time.temporal.Temporal
しかし、このメソッドは署名付きのインターフェースメソッドを実装しています
Temporal minus(TemporalAmount amount)
これは、共変の戻り値の型付けにより許可されますが、メソッド ルックアップの動作方法により、 を返すメソッドを実行時にルックアップしても、 を返すTemporal
メソッドが見つかりませんLocalTime
。したがって、コンパイラは、同じ署名を持つ通常禁止されているメソッドを作成しますが、Temporal
. このメソッドは、 を返すバージョンを呼び出しますLocalTime
。実行時に、戻り値の型を必要とする呼び出しTemporal
はブリッジ メソッドを見つけ、すべてがうまくいきます。
このブリッジ メソッドは通常は表示されませんが、javap
出力に表示されるため、現在の混乱につながっています。
ソース: http://www.artima.com/weblogs/viewpost.jsp?thread=354443
以下javap -c
は、 のブリッジ メソッドの 1 つを逆アセンブリしたもので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