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?
A function can take parameters which are just values you supply to the function so that the function can do something utilising those values. These parameters are just like variables except that the values of these variables are defined when we call the function and are not assigned values within the function itself.
When a function is called, all of the parameters of the function are created as variables, and the value of each of the arguments is copied into the matching parameter. This process is called pass by value.
Parameters and Arguments Information can be passed to functions as a parameter. Parameters act as variables inside the function. Parameters are specified after the function name, inside the parentheses.
There are two ways to pass arguments to a function: by reference or by value. Modifying an argument that's passed by reference is reflected globally, but modifying an argument that's passed by value is reflected only inside the function.
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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With