Java 8では、戻り値の型が異なる(ただし互換性のある)2つのインターフェースがある場合、リフレクションにより、2つのメソッドの1つがデフォルトのメソッドであることが示されます。
たとえば、次のコードスニペットを取ります。
package com.company;
import java.lang.reflect.Method;
interface BarInterface {}
class Bar implements BarInterface {}
interface FooInterface {
public BarInterface getBar();
}
interface FooInterface2 extends FooInterface {
public Bar getBar();
}
class Foo implements FooInterface2 {
public Bar getBar(){
throw new UnsupportedOperationException();
}
}
public class Main {
public static void main(String[] args) {
for(Method m : FooInterface2.class.getMethods()){
System.out.println(m);
}
}
}
Java 1.8は次の出力を生成します。
public abstract com.company.Bar com.company.FooInterface2.getBar()
public default com.company.BarInterface com.company.FooInterface2.getBar()
これは奇妙に思えます。両方のメソッドが存在するためだけでなく、メソッドの1つが突然、そして不可解にデフォルトのメソッドになったためです。
Java 7で同じコードを実行すると、両方のメソッドのシグネチャが同じであることを考えると、混乱するかもしれませんが、少し予期しない結果が生じます。
public abstract com.company.Bar com.company.FooInterface2.getBar()
public abstract com.company.BarInterface com.company.FooInterface.getBar()
Javaは複数の戻り値の型をサポートしていないので、この結果はまだ奇妙です。
次の考えは明白です:「わかりました。これは、これらのメソッドに実装がないため、インターフェイスにのみ適用される特別な動作である可能性があります。」
違う。
class Foo2 implements FooInterface2 {
public Bar getBar(){
throw new UnsupportedOperationException();
}
}
public class Main {
public static void main(String[] args) {
for(Method m : Foo2.class.getMethods()){
System.out.println(m);
}
}
}
収量
public com.company.Bar com.company.Foo2.getBar()
public com.company.BarInterface com.company.Foo2.getBar()
何が起きてる?Javaがこれらを個別のメソッドとして列挙するのはなぜですか。また、インターフェースメソッドの1つが実装されていないデフォルトのメソッドになるように管理されているのはなぜですか。
これは、default
ユーザーが提供する方法ではなく、ブリッジ方法です。定義した親インターフェース。
public BarInterface getBar();
そして、これを実装する呼び出し可能なメソッドが必要です。
例えば
FooInterface fi = new Foo();
BarInterface bi = fi.getBar(); // calls BarInterface getBar()
ただし、それは共変の戻り値型を呼び出すことができる必要もあります。
FooInterface2 fi = new Foo();
Bar bar = fi.getBar(); // calls Bar getBar()
これらは同じメソッドですが、唯一の違いは、一方が他方を呼び出し、戻り値をキャストすることです。これを行うのはdefault
インターフェース上にあるため、実装があるように見えるメソッドです。
注:複数レベルのインターフェース/クラスがあり、それぞれに異なる戻り値のタイプがある場合、メソッドの数は累積します。
これを行う理由は、戻り値の型がシグネチャの一部であるため、JVM は戻り値の型が異なる複数のメソッドを持つことができるためです。私は呼び出し側が期待している戻り値の型を指定する必要があり、JVMは実際には共変戻り値の型を理解していません。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加