[lambda] Java 8における "機能インタフェース"の正確な定義


Answers

@FunctionalInterfaceページには別の説明があります

概念的には、機能的なインタフェースはちょうど1つの抽象メソッドを持っています。 デフォルトメソッドには実装があるため、抽象メソッドではありません。 インタフェースがjava.lang.Objectのパブリックメソッドの1つをオーバーライドする抽象メソッドを宣言している場合、インタフェースの実装にはjava.lang.Objectまたは他の場所からの実装があるため、インタフェースの抽象メソッドカウントにはカウントされません。

@FunctionalInterfaceを使用して、どのインタフェースが正しい機能インタフェースであるかをテストできます

例えば:

  • この作品

    @FunctionalInterface
    public interface FunctionalInterf {
    
        void m();
    
        boolean equals(Object o);
    
    }
    
  • これはエラーを生成します:

    @FunctionalInterface
    public interface FunctionalInterf {
    
        void m();
    
        boolean equals();
    
    }
    

    FunctionalInterfインタフェースで見つかった複数のオーバーライドしない抽象メソッド

Question

最近私はJava 8の開発を始めました。Javaのラムダ式の実装に不可欠な「機能インタフェース」という概念を理解することはできません。 Javaのラムダ関数にはかなり包括的なガイドがありますが、私は機能インタフェースの概念を定義する章についています 。 定義は次のようになります。

より正確には、機能インタフェースは、厳密に1つの抽象メソッドを持つインタフェースとして定義されます。

その後、彼は例に進み、その1つはComparatorインターフェースです:

public interface Comparator<T> {
    int compare(T o1, T o2);
    boolean equals(Object obj);
} 

私はComparator引数の代わりにラムダ関数を使うことができ、それが動作することをテストできました(つまり、 Collections.sort(list, (a, b) -> ab) )。

しかしComparatorインターフェースでは、 compareequals両方のメソッドが抽象メソッドであるcompare2つの抽象メソッドがあります。 したがって、定義でインターフェイスに厳密に1つの抽象メソッドを持たせる必要がある場合、これはどのように機能しますか? 私はここで何が欠けていますか?




Javaのドキュメントでは、

Object.equals(Object)をオーバーライドしないことは常に安全です。 ただし、このメソッドをオーバーライドすると、プログラムによって2つの異なるコンパレータが同じ順序を課すことをプログラムが判別できるようにすることによって、パフォーマンスが向上する場合があります。

コンパレータは特別でしょうか? たぶん、それはインターフェイスであるにもかかわらず、 compare()を呼び出すequals()デフォルト実装が何とかありますか? アルゴリズム的には、それは簡単です。

私は、インターフェイスで宣言されたすべてのメソッドが抽象的な(つまり、デフォルト実装なし)と考えていました。 しかし、多分私は何かを逃しています。




Links