【问题标题】:Abstract class as functional interface抽象类作为功能接口
【发布时间】:2014-08-27 21:54:24
【问题描述】:

在 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

为什么语言设计者会施加这个限制?

【问题讨论】:

  • 好问题...兼容性可能吗?
  • 这已经被问过并回答过......主要原因是未来的灵活性,预计 lambdas 与类实例有很大不同。
  • 在这里,阅读from the horse's mouth
  • @MarkoTopolnik 发布简短摘要和此链接作为答案。我只是讨厌在 cmets 中看到带有答案的“未回答”问题。 :-)
  • @StuartMarks 是的,你是对的。完成。

标签: java lambda functional-programming java-8


【解决方案1】:

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

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

我对 Java 的未来持乐观态度,但为了向前发展,我们有时 不得不放弃一些舒服的想法。 Lambdas-are-functions 打开 门。 Lambdas-are-objects 关闭它们。我们更喜欢看到那些门 保持打开状态。

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

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

在把这个用例扔到公共汽车下之前,我们做了一些语料库分析 找出与接口相比抽象类 SAM 的使用频率 SAM。我们发现在那个语料库中,只有 3% 的 lambda 候选 内部类实例以抽象类为目标。而且大部分 它们可以进行简单的重构,您在其中添加了 接受以接口为目标的 lambda 的构造函数/工厂。

【讨论】:

  • 我只想补充一点,这是 JSR-335 早期阶段最热门的话题之一。当我们第一次提出“仅接口”规则时,这似乎是有风险的。但由于这件事现在已经解决了好几年,我绝对相信我们做了正确的事情。由于放弃了一些极端用例,我们获得了显着的简单性和灵活性(以更好的性能和更灵活的未来语言发展的形式为所有用户带来)。
  • 我没有看到 Brian Goetz 在这里提供了任何想法。只是一些无意义的词。 Lambda 是匿名内部类的语法糖。那为什么要在糖里加苦?!
猜你喜欢
  • 2013-11-25
  • 1970-01-01
  • 2017-03-09
  • 2011-05-22
  • 2013-03-25
  • 1970-01-01
  • 1970-01-01
  • 2017-02-19
  • 1970-01-01
相关资源
最近更新 更多