2017-02-28 33 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

相關問題