抽象类作为功能接口

时间:2014-07-07 12:05:16

标签: java lambda functional-programming java-8

在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

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

1 个答案:

答案 0 :(得分:29)

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

  

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

     

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

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

  

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

     

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