Java 8类型推断错误,将lambda表达式赋给Object

时间:2017-08-03 15:19:15

标签: lambda casting java-8 type-inference

为什么java编译器会抱怨第一个语句,这是因为表达式() -> ""没有明确的类型,我的意思是它可能是Supplier <String>或自定义函数接口类型等等......?

Object emptyStringBuilder = () -> ""; // causes compiler error

Object emptyStringBuilder = (Supplier<String>)() -> "";

你能详细说明具体原因吗?

2 个答案:

答案 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可以是ProducerSupplier。因此,分配必须是@FunctionalInterface(或转换),以便可以进行类型推断。

JLS中,这些被定义为多重表达式(它们取决于使用它们的上下文 - 如泛型,方法引用,三元运算符)