Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java8 Lambdas and Exceptions

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.

like image 433
rompetroll Avatar asked Aug 27 '14 09:08

rompetroll


People also ask

How do you handle exceptions in lambda?

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); } });

Can we throw exceptions in lambda expression?

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.

Does Java 8 have lambdas?

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.


1 Answers

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...

like image 182
keisar Avatar answered Sep 28 '22 03:09

keisar