抽象类作为function接口

在java 8中,只有一个抽象方法的抽象类不是函数接口( JSR 335 )。

interface是一个function界面:

 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

为什么语言设计师强加了这个限制?

自从Lambda项目开始以来,这一直是一个重要的话题,并且已经收到了很多想法。 首席Java语言架构师Brian Goetz强烈支持将lambda视为一个函数 ,而不是一个对象 。 引用:

我相信,发展Java的最佳方向是鼓励更具function性的编程风格。 Lambda的作用主要是支持更多function类库的开发和使用

我对Java的未来感到乐观,但为了向前发展,我们有时不得不放弃一些舒适的想法。 Lambdas-are-functions打开了大门。 Lambdas-are-objects关闭它们。 我们更愿意看到那些门敞开。

这是引用来源的链接, 这是Brian最近的post,它重申了相同的哲学观点,并用更多,更实际的论点重申了这些观点:

使模型更简单为各种VM优化打开了大门。 (抛弃身份在这里是关键。)function是价值。 将它们建模为对象使它们比它们需要的更重,更复杂。

在将此用例丢弃到总线之前,我们进行了一些语料库分析,以发现与接口SAM相比,抽象类SAM的使用频率。 我们发现在该语料库中,只有3%的lambda候选内部类实例将抽象类作为目标。 其中大多数都适合简单的重构,你添加了一个构造函数/工厂,接受一个接口定位的lambda。