为什么我需要一个功能接口来处理 lambdas?

2022-09-01 00:57:14

我认为这个问题已经存在了,但我找不到它。

我不明白,为什么有必要有一个功能接口来使用lambdas。请考虑以下示例:

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:对不起,我显然不是母语人士,但确切地说是我自己:

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”可以使用一个方法。


答案 1

当你写:

TestInterface i = () -> System.out.println("Hans");

您为 .void hans()TestInterface

如果可以将 lambda 表达式分配给具有多个抽象方法的接口(即非功能接口),则 lambda 表达式只能实现其中一个方法,而其他方法未实现。

您无法通过将两个具有不同签名的 lambda 表达式分配给同一个变量来解决该问题(就像您不能将两个对象的引用分配给单个变量并期望该变量同时引用两个对象一样)。


答案 2

它们必须只包含一种方法的最重要原因是,否则很容易造成混淆。如果接口中允许使用多个方法,如果参数列表相同,lambda 应该选择哪种方法?

interface TestInterface {
    void first();
    void second(); // this is only distinguished from first() by method name
    String third(); // maybe you could say in this instance "well the return type is different"
    Object fourth(); // but a String is an Object, too !
}

void test() {
    // which method are you implementing, first or second ?
    TestInterface a = () -> System.out.println("Ido mein ado mein");
    // which method are you implementing, third or fourth ?
    TestInterface b = () -> "Ido mein ado mein";
}

推荐