2016-10-18 4 views
4

私はJava8ラムダ式の構文を理解していますが、xの特定の型宣言なしで次のコードが機能するのはなぜですか? 「バズ」はなぜ印刷されていますか?型なしのラムダ式

public class LambdaExpressions { 

    interface Foo { 
     void bar(Object o); 
    } 

    static void doo(Foo f) { 
     f.bar("baz"); 
    } 

    public static void main(String[] args) { 

     doo(x -> {System.out.println(x);}); 
    } 

} 
+0

@ cricket_007なぜ 'x'が魔法の' Foo'タイプなのか、 'System.out.println(x)'(より具体的にはラムダ)の呼び出しが 'Foo .bar'。 – Qix

+2

型は、lambdaが実装しようとしている関数インタフェースメソッドで指定されているので簡単に推論できます。したがって、型を明示的に宣言する必要はありません。 – Pshemo

+1

'System.out.println'は' Foo'が 'Consumer '(printlnとよく似ています)の 'Object'を受け入れるので、 – Rogue

答えて

6

インタフェースはstandard functional interface

あるので、それが唯一の抽象メソッドが含まれているので、それは機能的なインターフェースです。この方法は、ラムダ式x -> { System.out.println(x); }匿名クラスとして書き換えることができる

を一つのパラメータを受け取り、[ボイド]の値(この質問のために言い換え)

を返します。

new Foo() { 
    @Override 
    public void bar(Object x) { 
     System.out.println(x); 
    } 
} 

あなたがdooを呼び出す

は、あなたはとても "baz"xあり、そしてそれが印刷され、その後、 f.bar("baz");実行 f、この機能インタフェースを渡します。

1つのmainメソッドのすべて、これは

public static void main(String[] args) { 
    Foo f = new Foo() { 
     @Override 
     public void bar(Object x) { 
      System.out.println(x); 
     } 
    }; 

    f.bar("baz"); 
} 
1

fooはstandard functional interface.

あるため、本質的には、標準的な機能インタフェースは、1つだけの抽象関数を含んでいます。 Java 8では、インターフェイスのインスタンスを作成する代わりにラムダを使用して、より短く洗練された表記を行うことができます。

3

ようになり、パラメータxのタイプはspecificationあたりとして推測されです:

ラムダ式の仮パラメータ宣言型または推論型のいずれかを持つことができます。これらのスタイルは混在することはできません。ラムダ式ではパラメータの型の一部を宣言することはできませんが、他の型は推測することはできません。宣言された型を持つパラメータだけが修飾子を持つことができます。

この場合、メソッドはObjectを受け入れるメソッドで機能的インターフェイスを受け入れるので、コンパイラはタイプをObjectと推測します。

仮パラメータに推論型がある場合、これらの型はラムダ式の対象となる関数インタフェース型から導出されます(15.27.3項)。