2017-08-24 130 views
7

我在科特林定義的函數:如何聲明一個函數參數來接受拋出的函數?

fun convertExceptionToEmpty(requestFunc:() -> List<Widget>): Stream<Widget> { 
    try { 
     return requestFunc().stream() 
    } catch (th: Throwable) { 
     // Log the exception... 
     return Stream.empty() 
    } 
} 

我已經定義了一個Java方法與此簽名:

List<Widget> getStaticWidgets() throws IOException; 

我嘗試撰寫他們像這樣:

Stream<Widget> widgets = convertExceptionToEmpty(() -> getStaticWidgets()) 

當我編譯我得到這個錯誤:

Error:(ln, col) java: unreported exception java.io.IOException; must be caught or declared to be thrown

如何定義我的函數參數以接受拋出的函數?

+0

您可以嘗試註釋您的convertExceptionToEmpty函數以拋出IOException,這可能會繞過此錯誤。 – Piwo

+0

@piwo,我認爲這不會有幫助,異常來自''getStaticWidgets()''方法 –

回答

4

的問題是,Java有checked exceptions但科特林沒有。 requestFunc參數類型() -> List<Widget>將映射到功能接口Function0<List<Widget>>,但運算符invoke不會在Kotlin代碼中引發檢查異常。

所以你不能在lambda表達式中調用getStaticWidgets(),因爲它會拋出一個IOException,這是一個Java中檢查的異常。

由於您同時控制科特林和Java代碼,最簡單的解決方案是將參數類型更改() -> List<Widget>Callable<List<Widget>>,例如:

// change the parameter type to `Callable` ---v 
fun convertExceptionToEmpty(requestFunc: Callable<List<Widget>>): Stream<Widget> { 
    try { 
     //     v--- get the `List<Widget>` from `Callable` 
     return requestFunc.call().stream() 
    } catch (th: Throwable) { 
     return Stream.empty() 
    } 
} 

然後可以在Java8作爲進一步使用方法參照表達,例如:

Stream<Widget> widgets = convertExceptionToEmpty(this::getStaticWidgets); 

//OR if `getStaticWidgets` is static `T` is the class belong to 
//            v 
Stream<Widget> widgets = convertExceptionToEmpty(T::getStaticWidgets); 
0

恐怕沒有什麼可以做,但捕獲了異常:

Stream<Integer> widgets = convertExceptionToEmpty(() -> { 
     try { 
      return getStaticWidgets(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 

     return null; 
    }); 
相關問題