I wonder if someone could explain the following weirdness to me. I'm using Java 8 update 11.
Given this method
private <F,T> T runFun(Function<Optional<F>, T> fun, Optional<F> opt) { return fun.apply(opt) ; }
If I first construct a function Object, and pass that in to the method above, things compile.
private void doesCompile() { Function<Optional<String>, String> fun = o -> o.orElseThrow(() -> new RuntimeException("nah")); runFun(fun, Optional.of("foo")); }
But, if I inline the function as a lambda, the compiler says
unreported exception X; must be caught or declared to be thrown
private void doesNotCompile () { runFun(o -> o.orElseThrow(() -> new RuntimeException("nah")), Optional.of("foo")); }
Update: Turns out the error message was abbreviated by maven. If compiled directly with javac, the error is:
error: unreported exception X; must be caught or declared to be thrown runFun(o -> o.orElseThrow(() -> new RuntimeException("nah")), Optional.of("foo")); ^ where X,T are type-variables: X extends Throwable declared in method <X>orElseThrow(Supplier<? extends X>) T extends Object declared in class Optional
Also see here for runnable test code.
The most straightforward way would be to use a try-catch block, wrap the checked exception into an unchecked exception and rethrow it: List<Integer> integers = Arrays. asList(3, 9, 7, 0, 10, 20); integers. forEach(i -> { try { writeToFile(i); } catch (IOException e) { throw new RuntimeException(e); } });
A lambda expression body can't throw any exceptions that haven't specified in a functional interface. If the lambda expression can throw an exception then the "throws" clause of a functional interface must declare the same exception or one of its subtype.
Lambda Expressions were added in Java 8. A lambda expression is a short block of code which takes in parameters and returns a value. Lambda expressions are similar to methods, but they do not need a name and they can be implemented right in the body of a method.
This is what solved the problem for me:
instead of writing
optional.map(this::mappingFunction).orElseThrow(() -> new BadRequestException("bla bla"));
I wrote:
optional.map(this::mappingFunction).<BadRequestException>orElseThrow(() -> new BadRequestException("bla bla"));
Adding the explicit <BadRequestException>
helps with these lambda edge cases (which are quite annoying...)
UPDATE: This is in case you can't update to the latest JDK version, if you can you should...
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