java - 方法引用不符合功能接口(interface),但编译不会失败......是设计使然吗?

标签 java java-8

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

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() 返回一个 BigDecimal,而 Set.add()(实际上是Collection)返回一个boolean;
  • 因此上述两种方法的签名都不匹配Consumer
  • 但两个示例都可以编译。

但是这个不编译:

// whatever is returned; BigDecimal.ZERO, null... -> compile error
Stream.of(BigDecimal.ONE).forEach(b -> { return false; });

是设计使然吗?

最佳答案

Remember that a return type is not part of a method signature.对于您的第一个案例,我们转到 runtime evaluation of the lambda expression .

The method's body has the effect of evaluating the lambda body, if it is an expression, or of executing the lambda body, if it is a block; if a result is expected, it is returned from the method.

关于第二种情况

If the function type's result is void, the lambda body is either a statement expression or a void-compatible block.

你的不是,即。 Consumer#accept(Object) 的函数类型是void,但是你的 lambda 体既不是语句表达式也不是 a void-compatible block .它是一个值兼容的 block 。

Is it by design?

我说是的。在第二种情况下,您明确声明要返回一个值。但目标功能接口(interface)方法不允许这样做。

在你的第一个片段中

Stream.of(BigDecimal.ONE, BigDecimal.TEN).forEach(spent::add);

您只是拥有更大的灵 active 。该表达式可能有副作用,您可能希望忽略返回值。

关于java - 方法引用不符合功能接口(interface),但编译不会失败......是设计使然吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27209023/

相关文章:

java - 将对象的值与枚举的值进行比较

java - 将 Java 7 升级到 Java 8 - Java 8 字符串开关是否已弃用?

testing - Java 8 Lambda 的单元测试

java - 如何在应用某些函数后有效地计算集合的最大值

Javafx 8、scenebuilder 2 和带有 fontawesome 的 controlsfx?

java - 将 JBOSS 注释转换为 xml

java - 写入和读取名称中包含日期的文件

java - 在android上按时间对sqlite数据库进行排序

java - println 无法解析为变量

java - IntelliJ IDE for MyEclipse 中 `sout + Tab` 快捷方式的同义词