44

この質問はすでにどこかにあると思いますが、見つけることができませんでした。

ラムダを操作するために機能的なインターフェイスが必要な理由がわかりません。次の例を検討してください。

public class Test {

    public static void main(String...args) {
        TestInterface i = () -> System.out.println("Hans");
//      i = (String a) -> System.out.println(a);

        i.hans();
//      i.hans("Hello");
    }
}

public interface TestInterface {
    public void hans();
//  public void hans(String a);
}

これは問題なく動作しますが、コメント行のコメントを外すと、動作しません。なんで?私の理解では、コンパイラは2つのメソッドを区別できるはずです.2つのメソッドは異なる入力パラメータを持っているからです. 機能的なインターフェイスが必要で、コードを爆破するのはなぜですか?

編集:リンクされた重複は、異なるメソッドパラメーターについて尋ねているため、私の質問に答えませんでした。しかし、助けてくれたみんなに感謝します! :)

EDIT2:申し訳ありませんが、私は明らかにネイティブスピーカーではありませんが、正確には:

public interface TestInterface {
    public void hans();                 //has no input parameters</br>
    public void hans(String a);         //has 1 input parameter, type String</br>
    public void hans(String a, int b);  //has 2 input parameters, 1. type = String, 2. type = int</br>
    public void hans(int a, int b);     //has also 2 input parameters, but not the same and a different order than `hans(String a, int a);`, so you could distinguish both
}

public class Test {

    public static void main(String...args) {
        TestInterface i = () -> System.out.println("Hans");
        i = (String a) -> System.out.println(a);
        i = (String a, int b) -> System.out.println(a + b);
        i = (int a, int b) -> System.out.println(a);

        i.hans(2, 3);   //Which method would be called? Of course the one that would take 2 integer arguments. :)
    }
}

私が求めているのは、議論についてだけです。メソッド名は問題ではありませんが、各メソッドは異なる引数の一意の順序をとります。そのため、Oracle は、「Lambda-Interface」ごとに単一のメソッドを可能にする代わりに、この機能を実装できたはずです。

4

7 に答える 7

5

ラムダ関数を作成するために関数型インターフェイスを作成する必要はありません。インターフェイスを使用すると、将来の関数呼び出し用のインスタンスを作成できます。

あなたの場合、既存のインターフェイス Runable を使用できます

Runnable r = () -> System.out.println("Hans");

そして電話する

r.run();

->ラムダは、次の単なる省略形と考えることができます。

Runnable r = new Runnable() {
     void run() {
          System.out.println("Hans");`
     }
}

ラムダを使用すると、上記の例の内部で作成される匿名クラスは必要ありません。

ただし、これにはいくつかの制限があります。ラムダで使用されるインターフェイスと呼ばれるメソッドを特定するには、SAM (Single Abstract Method) である必要があります。その場合、方法は 1 つだけです。

詳細な説明については、次を参照してください。

Functional Interfaces の紹介 – Java 8 で再現された概念

于 2015-10-08T08:37:01.990 に答える
2
  • Java では、インターフェースが実装されている場合、そのすべての抽象メソッドを実装する必要があります (そうでない場合、実装するクラスはインターフェースでなければなりません)。

  • Java コンパイラは、メソッドを含むクラス定義と、このクラスをインスタンス化するステートメントを使用して、ラムダ式を内部的に展開します。現在、Java は 1 つ以上のラムダを 1 つのインターフェースに関連付ける方法をサポート/提供していません。

      public class Test {
          public static void main(String...args) {
              TestInterface i = () -> System.out.println("Hans"); // this will not compile as the implementation for public void hans(String a); can not be provided/is not found
              //i = (String a) -> System.out.println(a); //this can not add an implementation for 2nd method to i after compilation of 1st lambda
           }
      }
      public interface TestInterface {
          public void hans();
          public void hans(String a);
      }
    

これが、Java のラムダが 1 つのメソッドまたは機能インターフェイスを持つインターフェイスでのみ機能する理由です。

于 2021-01-20T10:34:16.020 に答える