为什么java编译器会抱怨第一个语句,这是因为表达式() -> ""
没有明确的类型,我的意思是它可能是Supplier <String>
或自定义函数接口类型等等......?
Object emptyStringBuilder = () -> ""; // causes compiler error
Object emptyStringBuilder = (Supplier<String>)() -> "";
你能详细说明具体原因吗?
答案 0 :(得分:4)
Lambda表达式实现@FunctionalInterface
- 一个只有一个公共非静态和非默认方法的接口。在第一种情况下,编译器从左侧获取类型 - Object
,因为它无法推断出lambda表达式的类型。编译器不会为您选择任何接口。并且Object
没有实现功能接口,因此编译器会抱怨这种情况。
在第二种情况下,您使用功能接口Supplier<T>
并将其分配给Object
,这在编译方面是正确的 - 编译器满足是因为您抛弃了特定类型(Supplier<T>
在那种情况下)到一般Object
(每个类继承自Object
类)。
答案 1 :(得分:2)
lambda表达式的类型推断从目标类型发生,这意味着当您编写类似这样的内容时:
() -> "";
这确实是Supplier
(对你而不是编译器),但是如果我有一个这样的类型声明了什么:
static interface Producer<T> {
T produce();
}
这意味着您的lambda可以是Producer
或Supplier
。因此,分配必须是@FunctionalInterface
(或转换),以便可以进行类型推断。
在JLS
中,这些被定义为多重表达式(它们取决于使用它们的上下文 - 如泛型,方法引用,三元运算符)