Java 8 では、第一級関数のサポートが導入され、関数を変数に割り当てることができます。この場合、変数は関数型である必要があり、関数型インターフェイス(抽象メソッドが 1 つだけのインターフェイス)によって定義されます。
したがって、次の定義を持つインターフェイスI
とクラスの例を考えてみましょう。A
interface I{ int foo(); }
class A implements I{
public int foo(){return 7;}
public static int bar(){return 11;}
}
型の変数にI
のインスタンスA
または のメソッドへのメソッド参照bar
を割り当てることができますA
。I
両方とも、次のようなtype の変数に格納できます。
I i1 = new A();
I i2 = A::bar;
前のコードをコンパイルした結果のバイトコードを分析すると、次のようになります。
0: new #2 // class A
3: dup
4: invokespecial #3 // Method A."<init>":()V
7: astore_1
8: invokedynamic #4, 0 // InvokeDynamic #0:foo:()LI;
13: astore_2
それi1 = new A();
は、対応する命令がと互換性7: astore_1
のある のインスタンスを格納していることは明らかです。しかし、 の結果として、 の結果を保存しています。A
I
i2 = A::bar
8: invokedynamic #4, 0
つまり、 an の結果invokedynamic
は常に、メソッド参照で割り当てる変数の型である対象の型のインスタンスになるということです。