Java 为什么可以';我不能将lambda分配给对象吗?
我试图将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
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没有施法,目标类型只是对象