Java 为什么可以';我不能将lambda分配给对象吗?

Java 为什么可以';我不能将lambda分配给对象吗?,java,java-8,Java,Java 8,我试图将lambda分配给对象类型: Object f = ()->{}; 这给了我一个错误的说法: The target type of this expression must be a functional interface 为什么会发生这种情况,以及如何做到这一点?这是不可能的。根据错误消息Object不是一个功能接口,它是一个带有单个公共方法的接口,因此您需要使用一个引用类型,例如 Runnable r = () -> {}; 这是因为Java语言中没有“lam

我试图将lambda分配给对象类型:

Object f = ()->{};
这给了我一个错误的说法:

 The target type of this expression must be a functional interface

为什么会发生这种情况,以及如何做到这一点?

这是不可能的。根据错误消息
Object
不是一个功能接口,它是一个带有单个公共方法的接口,因此您需要使用一个引用类型,例如

Runnable r = () -> {}; 

这是因为Java语言中没有“lambda类型”

当编译器看到lambda表达式时,它将尝试将其转换为您尝试目标函数接口类型的实例。只是糖

编译器只能将lambda表达式转换为声明了单个抽象方法的类型。这就是它所谓的“功能接口”。而
对象
显然与此不符

如果您这样做:

Runnable f = (/*args*/) -> {/*body*/};
然后Java将能够将lambda表达式转换为扩展
Runnable
的匿名类的实例。本质上,这与写作是一样的:

Runnable f = new Runnable() {
    public void run(/*args*/) {
        /*body*/
    }
};
我添加了注释
/*args*/
/*body*/
,只是为了让它更清楚,但它们不是必需的

Java可以推断lamba表达式必须是
Runnable
类型,因为类型签名是
f
。但是,Java世界中没有“lambda类型”

如果您试图创建一个在Java中不起任何作用的泛型函数,那么您不能。Java是100%静态类型和面向对象的


匿名内部类和lambdas表达式之间存在一些差异,但您可以将它们视为语法糖,用于使用单个抽象方法实例化类型的对象。

此lambda将定义什么方法?不仅仅是语法糖。在Java中,lambda比创建匿名类更有效。@Thiago Negri:“在编码方面”存在差异。首先,
this
super
的含义完全不同。第二,不允许使用lambda参数名,这会隐藏局部变量,而方法参数可能会隐藏。第三,使用
(一个下划线)作为lambda参数名将在内部类中出现警告时生成错误。当然,匿名内部类可以扩展非
接口
类,并具有字段和多个方法等。仅列举一些区别。@Holger:我不知道。谢谢你指出这一点。我对答案进行了编辑以反映这一点。@Holger:“首先,this和super的含义完全不同。”是的,但没有人说里面的东西不能简化为语法糖的一部分。在lambda中使用
this
super
时,它与内部类中的
OuterClass.this
OuterClass.super
相同。“第二,你是不允许的……第三,使用…”lambda是匿名类的语法糖,这意味着lambda可以作为匿名类编写;并不是说一个匿名类一定可以写成lambda。@newacct:你可以将一个内部类表述为语义等价的类,这不是问题所在。您甚至可以在没有内部类的情况下制定等价的代码,但是,关键是转换并不像这个答案中所写的那么容易。考虑到在源代码级别上存在大量差异,并且在低级别上工作完全不同,最大的问题是为什么它被认为是内部类的语法糖。实际上,您可以将内部类和lambda表达式都看作是具有某些特性的顶级类的语法糖。当然,如果您真的认为需要,可以将任何对象分配给对象变量。代码>对象f=(可运行的)(->{}
@MichałPolitowski u应该已经回答了。。。但是为什么这里需要施法?@texasbruce没有施法,目标类型只是
对象