为什么必须用lambda体中的完整代码块来包含throw语句?

Dra*_*vic 37 java lambda exception java-8

如果lambda函数中有一个语句,我们可以省略为它定义完整的代码块:

new Thread(() -> System.out.println());
Run Code Online (Sandbox Code Playgroud)

为什么抛出异常的语句不是这种情况?这会产生一个编译错误,说明'{' expected:

new Thread(() -> throw new RuntimeException());
Run Code Online (Sandbox Code Playgroud)

当然,将lambda主体封装在代码块中可以:

new Thread(() -> {
    throw new RuntimeException();
});
Run Code Online (Sandbox Code Playgroud)

Eug*_*ene 24

AFAIK jls说lambda体必须是:

表达式.它是这样的:

new Thread(() -> throw new RuntimeException());
Run Code Online (Sandbox Code Playgroud)

既不是,编译器以某种方式通知你.

声明如下:

 new Thread(() -> {
     throw new RuntimeException();
 });
Run Code Online (Sandbox Code Playgroud)

使它成为一个块.以下是相关部分:

块是大括号内的语句,本地类声明和局部变量声明语句的序列.

  • 我承认,@JoeG我没想到会有这么多人投票.OP正在问为什么这不能编译,而不是为什么JLS是这样编写的,至少是我在阅读之后看到它的原因. (2认同)

hol*_*ava 20

在Java8中,lambda体的语法只接受表达式.而抛出异常是一个声明,而不是表达.

throwStatement: 'throw' expression ';' ;

lambdaBody: expression | block;

expression: lambdaExpression | assignmentExpression;

block : '{' blockStatements? '}' ;
Run Code Online (Sandbox Code Playgroud)

如果需要,可以通过在下一个jdk版本中throwStatement加入来增强lambdaBody它.实际上,正如你上面提到的,我们需要这样做 例如:

lambdaBody: expression | block | throwStatement;
Run Code Online (Sandbox Code Playgroud)


man*_*uti 14

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

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

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

表达式lambda(C#):

(input parameters) => expression
Run Code Online (Sandbox Code Playgroud)

语句lambda(C#):

(input parameters) => {statement;}  
Run Code Online (Sandbox Code Playgroud)

本MSDN文档页面中介绍了该语法.

在上一个帖子中提到了在其他选项中选择此语法的基本原理:

选择这种语法的决定是双重的:

  • 语法在大多数主观测量中得分"相当不错"(尽管它看起来很糟糕,就像所有其他人一样).特别是,它适用于作为方法参数(常见情况)的"小"lambda,并且也适用于大型(多语句)lambdas.

  • 尽管进行了广泛的搜索,但在替代品中没有明显的赢家(每种形式都有一些好的方面,有些方面确实不是很好,而且没有明显优于其他形式的形式).因此,我们认为最好选择一些已经证明在两种语言中运行良好的东西,这些语言最像Java-C#和Scala,而不是发明新东西.


归档时间:

查看次数:

793 次

最近记录:

8 年,6 月 前