表达式的目标类型必须是函数接口——为什么需要这样做



我已经回答了很多标题相同的问题,但我没有得到我想要的答案。

在下面的Greeter类中,有一个简单的sysout。据我所知,lambda关心的是签名(即返回类型和参数数量)。但如果我删除

int add(int a);

它非常有效,因为编译器会检查Greeting接口中是否有任何不带参数且返回类型为void的方法。

但当我把那个方法放在那里时,我会得到主题行中提到的编译错误,根据我的理解,编译器会去Greeting接口,它会看到有两个方法。但是,不应该有歧义,因为我的lambda表达式查找返回类型为void且只有一个参数的方法。基于这种类比,只有一种方法,因此理想情况下不应出现错误。

我知道我的类比是错误的,我知道它一定是一个函数接口,但我也认为我上面提到的过程正是编译器的工作方式。

有人能告诉我哪里错了吗?编译器在我的例子中是如何工作的?

问候界面

package lambadas;
public interface Greeting {
void perform();
int add(int a);
}

贪婪等级

package lambadas;
public class Greeter {
public static void main(String[] args) {
Greeting l = () -> System.out.println("hello");
l.perform();
}
}

HelloWorldGreeting

package lambadas;
public class HelloWorldGreeting implements Greeting {
@Override
public void perform() {
System.out.println("hello world.!");
}
@Override
public int add(int a) {
return 0;
}
}

@FunctionalInterface-注释您的界面,并看到它崩溃了。只允许使用单个抽象方法。

首先问自己一个问题:如果可以用这种方式实现Greeting,那么在调用l.add(0)时会发生什么?NoSuchMethodError?未定义的行为?你可能不想要——语言设计师也不想要。

通过强制函数接口作为lambda表达式的目标类型,编译器可以保证这些接口没有部分实现。这与如果HelloWorldGreeting也没有实现add(int),则会出现编译器错误的原因完全相同:您提供了1个实现,但有2个方法要实现。

因此,这实际上并不是要将lambda与特定方法进行匹配,而是要创建它实现的接口的有效实例。

相关内容

  • 没有找到相关文章

最新更新