如何声明一个函数参数来接受抛出的函数?
问题描述:
我在科特林定义的函数:如何声明一个函数参数来接受抛出的函数?
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
如何定义我的函数参数以接受抛出的函数?
答
的问题是,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);
答
恐怕没有什么可以做,但捕获了异常:
Stream<Integer> widgets = convertExceptionToEmpty(() -> {
try {
return getStaticWidgets();
} catch (IOException e) {
e.printStackTrace();
}
return null;
});
您可以尝试注释您的convertExceptionToEmpty函数以抛出IOException,这可能会绕过此错误。 – Piwo
@piwo,我认为这不会有帮助,异常来自''getStaticWidgets()''方法 –