Java 8 Lambda function that throws exception?

后端 未结 26 1716
臣服心动
臣服心动 2020-11-22 03:14

I know how to create a reference to a method that has a String parameter and returns an int, it\'s:

Function         


        
26条回答
  •  终归单人心
    2020-11-22 03:28

    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):

    @FunctionalInterface
    public interface ThrowingConsumer extends Consumer {
    
        @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 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 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 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) 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)));
    

提交回复
热议问题