2016-08-13 9 views
2

JAVA8では、内部クラスをラムダ式に置き換えることができます。ラムダ式を使用するときにどのメソッドをオーバーライドするべきかをJavaがどのように知っているか

Comparator c = (a, b) -> Integer.compare(a.length(), b.length()); 

Runnable java8Runner =() ->{System.out.println("I am running");}; 

このlambdaは正しい方法を無効にする必要がありますか?上記の例では、それらはrun()compare()です。

+2

* raw * 'Comparator'を使用すると、コンパイラは' a'と 'b'の型が何であるか分からないので、最初の例はコンパイルされません。 'Comparator 'のようなものに変更するとコンパイルされます。 – Andreas

答えて

4

Thiloが正しいです。潜在的に複数のデフォルトの方法が、1つの単一の抽象メソッド:機能インタフェースは、複数のメソッドを持っている可能性があるため、それにも関わらず

、用語

シングル・メソッド・インターフェース

は、より適切ではありません。
例えば、それは有効な機能のインターフェースである:

@FunctionalInterface 
public interface MyInterface { 

    Integer getResult(); 
    default boolean isNoResult(){ 
     return getResult()==null; 
    } 
} 

発現ラムダは、機能インタフェースのコンテキストで使用することができます。 機能インタフェースは、1つの単一の抽象メソッドを指定するJavaインタフェースです。 あなたの例では、ComparatorとRunnableには抽象メソッドが1つしかありません。ここ 詳細:https://docs.oracle.com/javase/8/docs/api/java/lang/FunctionalInterface.html

どのようにJVMノウハウ、このラムダは右のメソッドをオーバーライドする必要がありますか?上記の の例では、run()およびcompare()です。コンパイラは、実際に明示的なメッセージでそれについて文句を言うだろう:
この式のターゲット・タイプは、機能的でなければならないあなたがいない機能インタフェースを持つラムダ式を使用する場合は、コンパイルエラーになりウィル

インタフェース

だから、それは必須ではありません場合でも、あなたは目的が機能インタフェースであることにインターフェイスを作成する場合、それをチェックするために、コンパイラを強制する注釈@FunctionalInterfaceでそれを宣言することをお勧めが有効です機能的インタフェース:1つの単一の抽象メソッド。このようにして、あなたのインタフェースが有効な機能インタフェースかどうかをすぐに知ることができます。
Java 8のJDKクラスではそういったことがあります。

+1

これは完全な画像ではありません。機能的なインタフェースには 'java.lang.Object'のメソッドと一致しないちょうど1つの' abstract'メソッドがあります。これは、java.lang.Objectで宣言されたメソッドに 'boolean equals(Object)'が2つの 'abstract'メソッドを持つにもかかわらず、' Comparator'が機能インタフェースである理由です。 – Holger

+0

あなたはObjectクラスのメソッドが機能的インタフェースによって考慮されていないということは正確です – davidxxx

7

これは、シングルメソッドインタフェースによって容易になります。これらのインタフェースには単一の(抽象的)メソッドしかありません。あいまいさがある場合、省略形のラムダ構文は使用できません。

@FunctionalInterfaceアノテーションを使用すると、コンパイラにインターフェイス用にこれを強制することができます(ただし、インターフェイスを使用しなくてもラムダでインターフェイスを使用できます)。

関連する問題