[英]The target type of expression must be a functional interface – why is this needed?
我已经经历了很多具有相同标题的问题,但我没有得到我正在寻找的答案。
在下面的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个实现,但有两种方法可以实现。
所以这并不是关于将lambda与特定方法匹配,而是关于创建它实现的接口的有效实例。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.