2017-08-24 33 views
7

tôi đã xác định một hàm trong Kotlin:Làm cách nào để khai báo một tham số hàm để chấp nhận các hàm ném?

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

tôi đã xác định một phương pháp Java với chữ ký này:

List<Widget> getStaticWidgets() throws IOException; 

tôi cố gắng để soạn họ như vậy:

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

Khi Tôi biên dịch tôi gặp phải lỗi này:

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

Làm cách nào để xác định các tham số chức năng của tôi để chấp nhận một hàm ném?

+0

Bạn có thể thử chú thích hàm convertExceptionToEmpty của mình để ném IOException, có thể bỏ qua lỗi này. – Piwo

+0

@piwo, tôi không nghĩ rằng điều này sẽ giúp ích, ngoại lệ đến từ phương thức 'getStaticWidgets()' ' –

Trả lời

4

Vấn đề là Java có checked exceptions nhưng Kotlin không. Loại tham số requestFunc () -> List<Widget> sẽ được ánh xạ tới giao diện chức năng Function0<List<Widget>> nhưng toán tử invoke không ném ngoại lệ đã kiểm tra trong mã Kotlin.

Vì vậy, bạn không thể gọi số getStaticWidgets() trong biểu thức lambda vì nó ném một IOException là ngoại lệ được kiểm tra trong Java.

Vì bạn kiểm soát cả mã Kotlin và Java, giải pháp đơn giản nhất là thay đổi kiểu tham số () -> List<Widget>-Callable<List<Widget>>, ví dụ:

// 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() 
    } 
} 

Sau đó bạn có thể sử dụng phương pháp biểu tham khảo trong Java8 như thêm , ví dụ:

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

Tôi sợ không có gì bạn có thể làm nhưng bắt ngoại lệ đó là:

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

     return null; 
    }); 
Các vấn đề liên quan