2017-02-28 32 views
1

我有这样的代码:为什么lambda表达式的主体只能由throws语句组成?

public class Sample { 
    public static void useCallable(Callable<Integer> expression){} 

    public static void main(String[] args){ 
    useCallable(()->{throw new IOException();}); 
    } 
} 

其编译并运行良好。

但是,不应该Callable<Integer>不采取任何输入和返回一个整数?

()->{throw new IOException();}不返回任何内容,那么为什么它是一个有效的Callable<Integer>表达式?

+0

[请参考提问之前的文档](https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Callable.html#call()) –

+0

@JudeNiroshan该文档是什么说关于没有返回声明的lambda表达式? – shmosel

回答

4

出于同样的原因,这种方法编译:

Integer foo() throws Exception { 
    throw new IOException(); 
} 

这对于同样的原因,因为这方法编译:

Integer foo() throws Exception { 
    if (hasFoo()) { 
     return getFoo(); 
    } else { 
     throw new IOException(); 
    } 
} 

引述JLS

如果一个方法被声明为返回类型(第8.4.5节),那么如果方法的正文可以正常完成,则会发生编译时错误( §14.1)。

“正常完成”是什么意思?按照JLS(重点煤矿),

如果所有的步骤都进行了描述,没有迹象突然完成的,该报表正常完成说。然而,某些事件可以防止从声明正常完成:

  • break(§14.15),continue(§14.16),和return(§14.17)语句引起传送控制的,可能会阻止正常完成包含它们的陈述。

  • 某些表达式的评估可能会抛出Java虚拟机的异常(第15.6节)。 明确的throw(§14.18)声明也会导致异常。异常导致可能阻止正常完成语句的控制权转移。

换言之,与返回类型必须要么返回或抛出的方法。你的是后者,所以它是有效的。

+1

作为一个附录,除了突然完成的可能性之外,从来没有完成也阻止正常完成,所以'useCallable(() - > {while(true);});'也是有效的。 – Holger

相关问题