首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >方法引用不符合功能接口,但编译不会失败.是故意的吗?

方法引用不符合功能接口,但编译不会失败.是故意的吗?
EN

Stack Overflow用户
提问于 2014-11-30 01:20:52
回答 1查看 334关注 0票数 1

在下面的代码片段中,forEach()的两种用法编译:

代码语言:javascript
复制
public static void main(String[] args)
{
    BigDecimal spent = BigDecimal.ZERO;
    Stream.of(BigDecimal.ONE, BigDecimal.TEN).forEach(spent::add);

    Set<BigDecimal> set = new HashSet<>();
    Stream.of(BigDecimal.ONE, BigDecimal.TEN).forEach(set::add);
}

我意识到第一个例子(BigDecimal是不变的)的缺陷;问题不在这里:

  • StreamforEach()Consumer作为参数,SAM (注:单抽象方法)的签名表示返回void
  • 然而,BigDecimal.add()返回BigDecimalSet.add() (实际上是Collection的)返回boolean
  • 因此,上述两种方法的签名都与Consumer不匹配;
  • 然而,这两个示例都进行了编译。

但这并不能编译:

代码语言:javascript
复制
// whatever is returned; BigDecimal.ZERO, null... -> compile error
Stream.of(BigDecimal.ONE).forEach(b -> { return false; });

是故意的吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-11-30 01:37:43

请记住,返回类型不是方法签名的一部分。,对于你的第一个案例,我们去lambda表达式的运行时计算

该方法的主体具有这样的效果:如果是表达式,则计算lambda主体;如果它是块,则执行lambda主体;如果预期结果,则从方法返回它。

至于第二个案件

如果函数类型的结果是void,那么lambda主体要么是一个语句表达式,要么是一个与空兼容的块。

而你的不是.Consumer#accept(Object)的函数类型是void,但是您的lambda主体既不是语句表达式,也不是一个与空相兼容的块,它是一个与值兼容的块。

是故意的吗?

我答应了。在第二种情况下,您将显式地声明您正在返回一个值。但目标函数接口方法不允许这样做。

在你的第一个片段

代码语言:javascript
复制
Stream.of(BigDecimal.ONE, BigDecimal.TEN).forEach(spent::add);

你只是有更多的灵活性。表达式可能有副作用,您可能想忽略返回的值。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27209023

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档