Java 8中的函数式接口

10
我很难理解为什么lambda表达式可以赋值给某些函数接口,而不能赋值给其他函数接口。以下是使用Metrics库中的一些函数接口的示例:
Gauge<Double> foo = () -> { return null; };
RatioGauge bar = () -> { return null; };

第二个语句在Eclipse中有编译错误:
“此表达式的目标类型必须是一个函数式接口。”
据我所知,RatioGauge是一个函数式接口。我有什么遗漏吗?

函数式接口? - Rohit Jain
2
抽象类不是功能接口。 - m0skit0
2个回答

24

即使抽象类只有一个抽象方法,它也不是函数式接口。只有接口可以成为函数式接口。

来自 JLS 9.8

函数式接口是一种接口,它仅有一个抽象方法(除了Object的方法)... (强调添加)

最初的想法是让抽象类作为lambda表达式表示;它们被称为“SAM类型”,即“单一抽象方法”。但这证明是一个难以高效解决的问题。这个线程讨论了一些原因;基本上,基类的构造函数使它很难处理。


1
这真是太遗憾了,因为Lambda表达式基本上旨在替代匿名类,并且可以从接口或抽象类创建匿名类。 - Josh Stone
4
Lambda表达式从来就没有完全取代匿名类,只是针对某些特定情况而设计的。 - Rohit Jain
@RohitJain 有没有一种解决方法,可以在抽象类(具有单个抽象方法)与 lambda 结合使用? - Josh Stone
3
不需要太高明的技巧。您可以创建一个具体类,该类接收一个函数式接口,并使用它来实现抽象方法。例如,ThreadLocal就是这样做的(使用withInitial方法)。 - yshavit
1
@yshavit 非常感谢您提供的讨论链接。非常有用的信息。 - Josh Stone
显示剩余2条评论

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接