gpt4 book ai didi

java - 用于引发异常的内联 lambda 语法

转载 作者:行者123 更新时间:2023-12-02 02:00:12 24 4
gpt4 key购买 nike

对于返回 void 的 lambda,这是有效的:

Runnable b = () -> System.out.println("3");

但这不是:

Runnable b = () -> throw new RuntimeException("3");

我知道我可以将它放在带有大括号的 block 中,但是为什么这对于内联 lambda 来说不是有效的语法?

最佳答案

() -> foo 语法将 lambda 的主体定义为表达式 ( JLS 15.27.2 ),因此 抛出 new RuntimeExpression("3") 非常有意义 无法编译:这是一个语句,而不是一个表达式。所以真正的问题是,为什么 println 会编译?毕竟,这也是一个声明。

JLS 15.27.3 说:

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

您的示例都不是 block (void 兼容或其他),因此它们必须是语句表达式。这些在 JLS 14.8 中定义。并包括:

StatementExpression:
Assignment
PreIncrementExpression
PreDecrementExpression
PostIncrementExpression
PostDecrementExpression
MethodInvocation
ClassInstanceCreationExpression

注意方法调用——这就是让你的 println lambda 编译的原因。

简而言之:第一个 println 可以编译,因为它是语句表达式的 MethodInitation 形式,而 throw 则不能编译,因为语句表达式不包含 throw

请注意,所有语句表达式都是表达式(因此得名),所以这真正归结为这样一个事实: println 实际上是一个 void 类型的表达式,尽管事实上我们只是否曾将其视为一个声明。 (事实上​​,我们通常将其视为语句的原因是您只能将其用作语句表达式,如 JLS 15.1 中所述)。

关于java - 用于引发异常的内联 lambda 语法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51691879/

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