Java 8 Lambda function that throws exception? Java 8 Lambda function that throws exception? java java

Java 8 Lambda function that throws exception?


You'll need to do one of the following.

  • If it's your code, then define your own functional interface that declares the checked exception:

    @FunctionalInterfacepublic interface CheckedFunction<T, R> {   R apply(T t) throws IOException;}

    and use it:

    void foo (CheckedFunction f) { ... }
  • Otherwise, wrap Integer myMethod(String s) in a method that doesn't declare a checked exception:

    public Integer myWrappedMethod(String s) {    try {        return myMethod(s);    }    catch(IOException e) {        throw new UncheckedIOException(e);    }}

    and then:

    Function<String, Integer> f = (String t) -> myWrappedMethod(t);

    or:

    Function<String, Integer> f =    (String t) -> {        try {           return myMethod(t);        }        catch(IOException e) {            throw new UncheckedIOException(e);        }    };


You can actually extend Consumer (and Function etc.) with a new interface that handles exceptions -- using Java 8's default methods!

Consider this interface (extends Consumer):

@FunctionalInterfacepublic interface ThrowingConsumer<T> extends Consumer<T> {    @Override    default void accept(final T elem) {        try {            acceptThrows(elem);        } catch (final Exception e) {            // Implement your own exception handling logic here..            // For example:            System.out.println("handling an exception...");            // Or ...            throw new RuntimeException(e);        }    }    void acceptThrows(T elem) throws Exception;}

Then, for example, if you have a list:

final List<String> list = Arrays.asList("A", "B", "C");

If you want to consume it (eg. with forEach) with some code that throws exceptions, you would traditionally have set up a try/catch block:

final Consumer<String> consumer = aps -> {    try {        // maybe some other code here...        throw new Exception("asdas");    } catch (final Exception ex) {        System.out.println("handling an exception...");    }};list.forEach(consumer);

But with this new interface, you can instantiate it with a lambda expression and the compiler will not complain:

final ThrowingConsumer<String> throwingConsumer = aps -> {    // maybe some other code here...    throw new Exception("asdas");};list.forEach(throwingConsumer);

Or even just cast it to be more succinct!:

list.forEach((ThrowingConsumer<String>) aps -> {    // maybe some other code here...    throw new Exception("asda");});

Update: Looks like there's a very nice utility library part of Durian called Errors which can be used to solve this problem with a lot more flexibility. For example, in my implementation above I've explicitly defined the error handling policy (System.out... or throw RuntimeException), whereas Durian's Errors allow you to apply a policy on the fly via a large suite of utility methods. Thanks for sharing it, @NedTwigg!.

Sample usage:

list.forEach(Errors.rethrow().wrap(c -> somethingThatThrows(c)));


I think Durian's Errors class combines many of the pros of the various suggestions above.

To include Durian in your project, you can either: