在java 8中,只有一个抽象方法的抽象类不是功能接口(JSR 335)。
这个interface
是一个功能界面:
public interface MyFunctionalInterface {
public abstract void myAbstractMethod();
public default void method() {
myAbstractMethod();
}
}
但是这个abstract class
不是:
public abstract class MyFunctionalAbstractClass {
public abstract void myAbstractMethod();
public void method() {
myAbstractMethod();
}
}
所以我不能将抽象类用作lambda表达式和方法引用的目标。
public class Lambdas {
public static void main(String[] args) {
MyFunctionalAbstractClass functionalAbstractClass = () -> {};
}
}
编译错误是:The target type of this expression must be a functional interface
。
为什么语言设计师强加了这种限制?
答案 0 :(得分:29)
自从Lambda项目开始以来,这一直是一个重要的话题,并且已经收到了很多想法。首席Java语言架构师Brian Goetz强烈支持将lambda视为函数,而不是对象。引用:
我相信,发展Java的最佳方向是 鼓励更具功能性的编程风格。 Lambda的作用是 主要是为了支持更多的开发和消费 功能类库
我对Java的未来感到乐观,但我们有时会继续前进 不得不放弃一些舒适的想法。 Lambdas-are-functions打开 门。 Lambdas-are-objects关闭它们。我们更愿意看到那些门 离开了。
Here是引用来源的链接,而here是Brian最近的帖子,它重申了相同的哲学观点,并用更多更实际的论点重申了这些观点:
使模型更简单为各种VM打开了大门 优化。 (抛弃身份在这里是关键。)功能是 值。将它们建模为对象使它们更重,更复杂, 比他们需要的那样。
在将此用例丢弃到总线之前,我们进行了一些语料库分析 发现与界面相比,抽象类SAM的使用频率 地对空导弹。我们发现在那个语料库中,只有3%的lambda候选者 内部类实例将抽象类作为目标。而且大多数 他们适合简单的重构,你添加了一个 接受以接口为目标的lambda的构造函数/工厂。