How do I declare a function parameter to accept functions that throw?

I have defined a function in Kotlin:

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

I have defined a Java method with this signature:

List<Widget> getStaticWidgets() throws IOException;

I attempt to compose them like so:

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

When I compile I get this error:

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

How do I define my function parameters to accept a function that throws?


The problem is that Java has checked exceptions but Kotlin does not. The requestFunc parameter type () -> List<Widget> will be mapped to the functional interface Function0<List<Widget>> but the operator invoke doesn't throw a checked exception in Kotlin code.

So you can't call the getStaticWidgets() in lambda expression since it throws a IOException which is a checked exception in Java.

Since you control both the Kotlin and Java code, the simplest solution is to change the parameter type () -> List<Widget> to Callable<List<Widget>> , for example:

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

Then you can use Method Reference Expression in Java8 as further, for example:

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;
    });
链接地址: http://www.djcxy.com/p/97078.html

上一篇: SetInterval在多轮执行后会产生延迟

下一篇: 我如何声明一个函数参数来接受抛出的函数?