"".equals(s); 但这失败了,错误 boolean cannot be convert-6ren">
gpt4 book ai didi

java - 为什么消费者接受带有语句体而不是表达式体的 lambda?

转载 作者:IT老高 更新时间:2023-10-28 13:54:05 24 4
gpt4 key购买 nike

以下代码居然编译成功了:

Consumer<String> p = ""::equals;

这也是:

p = s -> "".equals(s);

但这失败了,错误 boolean cannot be convert to void as expected:

p = s -> true;

用括号修改第二个例子也失败了:

p = s -> ("".equals(s));

这是 Java 编译器中的错误还是我不知道的类型推断规则?

最佳答案

首先,有必要看看 Consumer<String> 是什么实际上是。 From the documentation :

Represents an operation that accepts a single input argument and returns no result. Unlike most other functional interfaces, Consumer is expected to operate via side-effects.

所以它是一个接受字符串并且不返回任何内容的函数。

Consumer<String> p = ""::equals;

编译成功,因为 equals可以接受一个字符串(实际上,任何对象)。 equals 的结果会被忽略。*

p = s -> "".equals(s);

这完全一样,但语法不同。编译器知道不添加隐式 return因为一个 Consumer不应返回值。它添加一个隐含的 return如果 lambda 是 Function<String, Boolean>不过。

p = s -> true;

这需要一个字符串 ( s ) 但因为 true是表达式而不是语句,结果不能以同样的方式忽略。编译器必须添加一个隐式 return因为表达式不能单独存在。因此,这个确实有一个返回值:一个 boolean 值。因此它不是 Consumer .**

p = s -> ("".equals(s));

同样,这是一个表达式,而不是一个语句。暂时忽略 lambda,您将看到 System.out.println("Hello"); 行如果将其括在括号中,同样将无法编译。


*来自 the spec :

If the body of a lambda is a statement expression (that is, an expression that would be allowed to stand alone as a statement), it is compatible with a void-producing function type; any result is simply discarded.

**来自 the spec (谢谢,Eugene):

A lambda expression is congruent with a [void-producing] function type if ... the lambda body is either a statement expression (§14.8) or a void-compatible block.

关于java - 为什么消费者接受带有语句体而不是表达式体的 lambda?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45460896/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com