当前位置: 首页 > 面试题库 >

消费者为什么接受带有声明主体而不是表达主体的lambda?

轩辕亮
2023-03-14
问题内容

以下代码令人惊讶地成功编译:

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

这个也是:

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

但这失败,并出现boolean cannot be converted to void预期的错误:

p = s -> true;

用括号将第二个示例修改也失败:

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

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


问题答案:

首先,值得一看的是什么Consumer<String>。从文档中:

表示一个 接受单个输入参数且不返回结果的操作 。与大多数其他功能接口不同,消费者应该通过副作用来操作。

因此,它是一个接受字符串且不返回任何内容的函数。

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

成功编译,因为equals可以使用String(以及实际上的任何Object)。equals的结果将被忽略。*

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

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

p = s -> true;

这需要一个String(s),但是由于true是表达式而不是语句,因此无法以相同的方式忽略结果。编译器 必须
添加一个隐式的,return因为表达式不能单独存在。因此,这 确实 有一个回报:一个布尔值。因此,它不是Consumer。**

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

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

*根据规格:

如果lambda的主体是语句表达式(即允许作为语句单独站立的表达式),则它与产生空隙的函数类型兼容;任何结果都将被简单丢弃。

**根据规格(感谢Eugene):

如果lambda主体是语句表达式(第14.8节)或与void兼容的块,则lambda表达式与[void-
production
]函数类型一致。



 类似资料:
  • 我不清楚< code>Subject和< code>BehaviorSubject之间的区别。只是一个< code>BehaviorSubject有< code>getValue()函数吗?

  • 我的远程接口是: 我的EJB实现是: 每次当我调用实体方法getFileId()时, 编辑: 当我试图使用JPA2.0提供的方法访问实体的主键时: 我得到了同样的错误回报。烦人??

  • 我必须写一个程序,它将接受Hashmap格式的body。我已经用Hashmap值创建了HttpEntity 我面临以下例外: 异常线程"main"org.springframework.web.client.RESTClientExcture: No HttpMessageConzer for[java.util.HashMap]atorg.springframework.web.client.R

  • 我有一个基本接口,并从中扩展了3个接口,和。在对进行了一些业务更改之后,现在与相同,但为了一致性,我不希望仅使用,而不是使用扩展接口。我试着这样做: 然后,ESLint警告我不要使用空接口。如果我不想禁用此规则,是否有方法将声明为与相同的接口?

  • 考虑以下示例: 我唯一想到的是,组件体内的函数可以访问它的属性,如道具、状态和体内的任何东西,包括函数,但我们也可以将它们作为外部函数的参数传递。所以这是唯一的“优点或缺点”,还是有更先进的东西?

  • 当我运行这个命令时,我得到了两个主题。我知道我创建了测试主题,但我看到了另一个名为“消费者偏移”的主题。从名称来看,这意味着它与消费者补偿有关,但它是如何使用的?