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

为什么必须在lambda主体中使用全代码块将throw语句括起来?

孙佑运
2023-03-14
问题内容

如果lambda函数中只有一条语句,我们可以省略为其定义完整的代码块的操作:

new Thread(() -> System.out.println());

为什么引发异常的语句不是这种情况?这将产生一个编译错误,指出'{' expected

new Thread(() -> throw new RuntimeException());

当然,将lambda主体包含在代码块中是可行的:

new Thread(() -> {
    throw new RuntimeException();
});

问题答案:

throw语句,那么,一个声明,而不是表达式所以它必须被置于括号内。根据本文的内容,Java专家组当时对lambda的语法进行了非正式调查,其中有四个选择:

  • 稻草人#(arglist)(expr) and #(arglist){statements}
  • BGGA :({ args -> statements } 类似于Scala和Groovy)
  • SotL#{ args -> statements}
  • 雷德蒙德(args) -> { statements }

最终,选择是根据该线程采用类似于C#的语法,据我所知,它看起来与上述最后一个选项最接近。在C#中,
表达式lambdas语句lambdas 之间是有区别的:

表达式lambda(C#):

(input parameters) => expression

语句lambda(C#):

(input parameters) => {statement;}

该语法在MSDN文档页面中进行了说明。

在上一个线程中提到了选择此语法而不是其他选项的原理:

选择此语法的决定是双重的:

  • 在大多数主观指标上,语法的得分为“很好”(尽管在某些情况下,它看起来很糟糕,就像其他所有方法一样)。特别是,它对于用作方法参数的“小”
    lambda效果很好(一种常见情况),对于大(多语句)lambda效果也很好。

* 尽管进行了广泛的搜索,但在替代方案中并没有明确的赢家(每种形式都有一些好的方面,而某些方面却不是很好,并且没有任何一种形式明显优于其他形式)。因此,我们觉得最好选择一种已经证明可以在两种最相似的Java(C#和Scala)语言中很好地工作的东西,而不是发明一些新东西。



 类似资料:
  • 问题内容: 当我回答另一个问题时我遇到了一个带有顶层语句的Node.js模块。例如: 这可以正常工作并且没有错误并可以打印: 在标准输出中,但不是“ ”- 实际停止执行。 但是根据ECMAScript 5.1中 的语句规范, 语义学 如果ECMAScript程序 包含不在内的return语句,则在语法上_被视为 _不正确 。 在上面显示的程序中没有任何功能。 那为什么不扔呢? 问题答案: TL;

  • 在我必须进行的猜测游戏中,我需要包含一个带有两个catch子句的try-catch块(一个多catch块用于我的两个自定义异常:和,一个块用于)。 我试图在程序中创建条件来抛出自定义异常,因为我不知道它们如何正常工作的逻辑。我有编译错误,希望能帮助重新运行我的程序,以便它正确地实现try-catch块。 我的自定义异常类: 我的程序有编译错误:

  • 问题内容: 我正在编写一个LoginRequest类的构造函数,该类扩展了一个名为JsobObjectRequest的类(来自Android的Volley框架,但这与问题完全无关) 使用此代码: 我收到错误:对super()的调用必须是构造函数主体中的第一条语句 相反,此代码可以正常编译: 但这实际上不是一回事吗?在这两种情况下,根据传递给子类构造函数的参数值,在调用超级构造函数之前都要进行一些简

  • 问题内容: 为什么必须始终在Java中初始化局部变量(包括基元)?为什么相同的实例变量不适用? 问题答案: 基本上,要求在读取变量之前为其分配值是一件好事。这意味着您不会意外阅读您不想要的内容。是的,变量可以具有默认值-但如果编译器可以证明您正在尝试读取尚未分配的内容,那么编译器是否可以捕获错误不是更好吗?如果要为局部变量提供默认值,则始终可以显式分配。 现在,对于局部变量来说,这很好-但是对于实

  • 问题内容: 即使等待1的linux手册页很好地说明了您需要让子进程不使其变成僵尸,但它根本无法说明原因。 我围绕一个Ever 循环计划了我的程序(这是我的第一个多线程程序,所以请原谅我的天真),该循环启动子进程,该子进程被ed淘汰,并确保自行终止。 我无法使用,因为这使并行计算变得不可能,因此我可能不得不添加一个存储子pid的进程表,并且不得不使用-不是立即执行,而是经过一段时间- 这是一个问题,

  • 关于在最新版本的GCC和Clang中编译有几个问题:实验::filessystems链接器错误 但是现在< code>filesystem已经被c 17接受,所以不再需要< code>experimental或< code>-lstdc fs标志,对吗? 错了,我甚至不能 只给了我< code >实验版本,我怎么能包括正式接受的版本呢?