26

機能インターフェースの定義は、「機能インターフェースは、( Object のメソッドを除いて) 1 つの抽象メソッドのみを持つインターフェースであり、したがって単一の機能コントラクトを表す」です。

この定義によれば、Comparable<T>は間違いなく機能的なインターフェースです。

ラムダ式の定義は、「ラムダ式はメソッドのようなものです。正式なパラメータのリストと、それらのパラメータで表現されたボディ (式またはブロック) を提供します。」

ラムダ式の評価により、関数型インターフェイスのインスタンスが生成されます。

したがって、ラムダ式の目的は、機能インターフェースの単一の関数を実装することによって、機能インターフェースのインスタンスを作成できるようにすることです。すなわち。単一の関数でインスタンスを作成できるようにします。

を見てみましょうComparable<T>。このインターフェイスは、単一の機能として使用するように設計されていますか? すなわち。この単一の関数のみを使用してインスタンスを作成するように設計されていますか?

のドキュメントはComparable<T>、「このインターフェイスは、それを実装する各クラスのオブジェクトに完全な順序付けを課します。この順序付けは、クラスの自然順序付けと呼ばれ、クラスの compareTo メソッドは、その自然比較メソッドと呼ばれます。」で始まります。

上記の文はComparable<T>、 が単一の関数として使用されるように設計されていないことを明確に示していますが、この単一の関数を追加することにより、インスタンスの自然な順序付けを持つクラスによって実装されることを常に意図しています。

ラムダ式を使用して作成するように設計されていないことを意味するのはどれですか?

ポイントは、Comparable のみのオブジェクトはなく、実装されることを意図しているため、クラスの追加関数として使用されるということです。

では、ラムダ式の作成をComparable<T>防止する Java 言語の方法はありますか? インターフェイスの設計者は、このインターフェイスがクラスによって実装されることを意図しており、ラムダ式を使用してこの単一のメソッドでインスタンスとして作成されることを意図していないと判断できますか?

インターフェイスがたまたま単一の抽象メソッドを持っているという理由だけで、それを関数型インターフェイスと見なすべきではありません。

おそらく、Java が NotFunctional のような注釈を提供する場合、このインターフェースがラムダ式の作成に使用されていないことをコンパイラーがチェックできます。

@NotFunctional
public interface Comparable<T> { public int compareTo(T t); }
4

4 に答える 4

28

ラムダ式は、単一の抽象メソッドを持つインターフェイスのインスタンスが必要な場合に使用できます。あなたが書いた、

インターフェイスがたまたま単一の抽象メソッドを持っているという理由だけで、それを関数型インターフェイスと見なすべきではありません。

これはまさに正しいです。単一の抽象メソッドを持つことは、インターフェイスの構造プロパティであり、ラムダで実装できるようにするものです。ただし、インターフェースがラムダで実装する意味があるか、または意味的に意味があるかどうかは、別の話です。後者が@FunctionalInterfaceアノテーションの目的です。インターフェイスに存在する場合、インターフェイスがラムダで実装されると便利であるという意図を示します。

特に、Comparableインターフェイスには@FunctionalInterface注釈がありません。

ラムダをComparable実装として使用することはおそらく無意味ですが、これが行われないようにするメカニズムを作成する理由はないようです。これを行うことがエラーの原因になるとは思えません。これは、そのようなメカニズムを開発する正当な理由となります。対照的に、注釈は、間違いなく間違っているが実際には害がないように見えるものを禁止するのではなく、プログラマーを正しい@FunctionalInterface方向に導くことを目的としています。

于 2014-08-10T00:50:28.200 に答える
8

この問題は、「メソッド」と「関数」の微妙な違いから生じます。

関数の出力値は、その関数に入力される引数のみに依存します。

ただし、メソッドの出力は、関数への入力である引数に依存しますが、オブジェクトの状態 (インスタンス変数) にも依存する場合があります。

つまり、どの関数もメソッドですが、すべてのメソッドが関数であるとは限りません。

たとえば、インターフェイス Comparator のメソッド compare は、その引数のみに依存します。ただし、Comparable インターフェイスの compareTo メソッドは、比較対象のオブジェクトの状態に依存するため、クラスに実装する必要があります。

そのため、 Comparable でさえ abstarct メソッドを 1 つ持っていますが、意味的にはそれを関数型インターフェイスと見なすべきではありません。

于 2015-04-17T11:46:03.210 に答える