加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – 为什么消费者接受语句体而不是表达体的lambdas?

发布时间:2020-12-15 07:38:58 所属栏目:Java 来源:网络整理
导读:以下代码令人惊讶地成功编译: ConsumerString p = ""::equals; 这个也是: p = s - "".equals(s); 但这是失败的错误布尔值无法按预期转换为void: p = s - true; 使用括号修改第二个示例也会失败: p = s - ("".equals(s)); 它是Java编译器中的错误还是我不
以下代码令人惊讶地成功编译:

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

这个也是:

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

但这是失败的错误布尔值无法按预期转换为void:

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.

所以这是一个接受String并且不返回任何内容的函数.

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

编译成功因为equals可以采用String(实际上是任何Object).等于的结果只是被忽略了.*

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

这完全相同,但语法不同.编译器知道不添加隐式返回,因为Consumer不应返回值.如果lambda是一个函数< String,Boolean&gt ;,它将添加一个隐式返回.虽然.

p = s -> true;

这需要一个String(s),但因为true是表达式而不是语句,所以不能以相同的方式忽略结果.编译器必须添加隐式返回,因为表达式本身不能存在.因此,这确实有一个返回:布尔值.因此,它不是消费者.**

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

同样,这是一个表达,而不是一个陈述.暂时忽略lambdas,你会看到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 (07004) or a void-compatible block.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读