Java 抽象类作为函数接口

Java 抽象类作为函数接口,java,lambda,functional-programming,java-8,Java,Lambda,Functional Programming,Java 8,在Java8中,只有一个抽象方法的抽象类不是函数接口() 此接口是一个功能接口: public interface MyFunctionalInterface { public abstract void myAbstractMethod(); public default void method() { myAbstractMethod(); } } 但是这个抽象类不是: public abstract class MyFunctionalAbstra

在Java8中,只有一个抽象方法的抽象类不是函数接口()

接口
是一个功能接口:

public interface MyFunctionalInterface {
    public abstract void myAbstractMethod();
    public default void method() {
        myAbstractMethod();
    }
}
但是这个
抽象类
不是:

public abstract class MyFunctionalAbstractClass {
    public abstract void myAbstractMethod();
    public void method() {
        myAbstractMethod();
    }
}
因此,我不能将抽象类用作lambda表达式和方法引用的目标

public class Lambdas {
    public static void main(String[] args) {
        MyFunctionalAbstractClass functionalAbstractClass = () -> {};
    }
}
编译错误为:
此表达式的目标类型必须是函数接口


语言设计者为什么要施加这种限制?

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

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

我对Java的未来很乐观,但为了向前发展,我们有时 不得不放弃一些舒适的想法。lambda是打开的函数 门。lambda是关闭它们的对象。我们更喜欢看那些门 左开

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

简化模型为各种虚拟机打开了大门 优化。(这里的关键是放弃标识。)函数是 价值观将它们建模为对象会使它们更重、更复杂, 比他们需要的要多

在发布这个用例之前,我们做了一些语料库分析 了解与接口相比,抽象类SAM的使用频率 萨姆。我们发现,在该语料库中,只有3%的lambda候选 内部类实例的目标是抽象类。大部分 它们可以进行简单的重构,您可以在其中添加 接受接口目标lambda的构造函数/工厂


好问题。。。兼容性可能吗?这已经被问过并回答过了。。。主要原因是未来的灵活性,在这种情况下,lambda将与类实例有很大的不同。在这里,请阅读。@MarkoTopolnik发布一个简短的摘要,并将此链接作为答案。我只是讨厌在评论中看到“未回答”的问题和答案。:-)@斯图尔特马克是的,你是对的。完成。我要补充的是,这是JSR-335早期最热门的话题之一。当我们第一次提出“仅限接口”规则时,似乎有风险。但是,由于这已经有好几年的时间来解决,我绝对相信我们做了正确的事情。我们放弃了一些极端情况下的用例,从而获得了显著的简单性和灵活性(所有用户都会获得更好的性能和更灵活的未来语言演变)。是的,事实上,我认为这一方面为Java带来了Lambda项目的最高整体价值。在深层次上,它似乎是“正确的”,甚至比我们在语言发展过程中看到的许多其他功能都更正确,并且为Java的未来开辟了新的、令人兴奋的方向。我看不到Brian Goetz在这里提供了任何想法。只是一些无聊的话。lambda是匿名内部类的语法糖。那为什么要在糖里加苦@DIM lambda不是匿名内部类的语法糖,这就是重点。你有什么权力提出相反的主张?