【问题标题】:Functional interfaces in Java 8Java 8 中的函数式接口
【发布时间】:2014-04-01 19:03:05
【问题描述】:

我很难弄清楚为什么 lambda 表达式可以分配给某些功能接口,但不能分配给其他接口。一个例子,使用来自Metrics library的一些功能接口:

Gauge<Double> foo = () -> { return null; };
RatioGauge bar = () -> { return null; };

第二条语句有编译错误(在 Eclipse 中):

此表达式的目标类型必须是函数式接口

据我所知,RatioGauge is a functional interface。我错过了什么吗?

【问题讨论】:

  • 功能性接口?
  • 抽象 不是功能性接口

标签: java java-8 codahale-metrics


【解决方案1】:

抽象类(即使它只有一个抽象方法)不是函数式接口。只有一个接口可以是一个。

来自JLS 9.8

一个函数式接口是一个接口,它只有一个抽象方法(除了 Object 的方法)...(强调)

最初的想法让抽象类表示为 lambda;它们被称为“SAM 类型”,代表“单一抽象方法”。事实证明,这是一个难以有效解决的问题。 This thread 谈了一点原因;基本上,基类的构造函数很困难。

【讨论】:

  • 这真是太可惜了,因为 lambda 表达式基本上是为了替换匿名类,并且可以从接口或抽象类创建匿名类。
  • @JoshStone 好吧,lambda 表达式从来没有打算完全取代匿名类,而只是为了某些场景。
  • @RohitJain 是否有一种解决方法可以将 lambda 与抽象类(使用单个抽象方法)结合使用?
  • @JoshStone 一点也不聪明。您可以创建一个具有功能接口的具体类,并使用它来实现抽象方法。 ThreadLocal 会这样做,例如 (withInitial)
  • @yshavit 非常感谢您提供的讨论链接。很棒的信息。
【解决方案2】:

一个函数接口只能有一个抽象方法(Object类的方法除外)。

Gauge.java的源代码= http://grepcode.com/file/repo1.maven.org/maven2/com.codahale.metrics/metrics-core/3.0.0/com/codahale/metrics/Gauge.java#Gauge

RatioGauge.java 的源代码= http://grepcode.com/file/repo1.maven.org/maven2/com.codahale.metrics/metrics-core/3.0.0/com/codahale/metrics/RatioGauge.java

注意 Gauge.java 只有一个抽象方法,而 RatioGauge 有很多方法。

【讨论】:

    猜你喜欢
    • 2013-12-01
    • 2018-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-21
    • 1970-01-01
    • 2018-10-27
    • 1970-01-01
    相关资源
    最近更新 更多