Java 8 Lambda 捕获异常问题
这个问题是在使用CompletableFuture.supplyAsync()方法时遇到的,异步调用的方法显示的定义了一个Checked异常,发现Lambda表达式无法干净利落地处理
这类异常。方案之一是在Lambda表达式中写入try catch代码块。这样地问题是每次都要写try catch,代码不够整洁。可以使用异常封装类地方式来使代码整洁。
Consumer 接口的异常封装
1 2 3 4 5
| @FunctionalInterface public interface ThrowingConsumer<T,E extends Exception> {
void accept(T t) throws E; }
|
Supplier 接口的异常封装
1 2 3 4 5
| @FunctionalInterface public interface ThrowingSupplier<T,E extends Exception> {
T get () throws E; }
|
代理工具类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| public class ThrowingWrapper {
public static <T>Consumer<T> throwingConsumerWrapper(ThrowingConsumer<T,Exception> throwingConsumer){ return i -> { try { throwingConsumer.accept(i); }catch ( Exception e ){ throw new RuntimeException(e); } }; }
public static <T>Supplier<T> throwingSupplierWrapper(ThrowingSupplier<T,Exception> throwingSupplier ){ return () -> { try { return throwingSupplier.get(); }catch ( Exception e ){ throw new RuntimeException(e); } }; } }
|
未封装前效果
1 2 3 4 5 6 7 8 9 10 11 12 13
| @Test public void test7() throws InterruptedException,ExecutionException{ CompletableFuture<Integer> completableFuture = CompletableFuture.supplyAsync(() -> { try { return cal1(); }catch ( IOException e ){ throw new RuntimeException(); } });
System.out.println(Thread.currentThread().getName() + "------------ "+completableFuture.get()); }
|
封装后效果
1 2 3 4 5
| @Test public void test8() throws InterruptedException,ExecutionException{ CompletableFuture<Integer> completableFuture = CompletableFuture.supplyAsync(ThrowingWrapper.throwingSupplierWrapper(() -> cal())); System.out.println(Thread.currentThread().getName() + "------------ "+ completableFuture.get()); }
|
实际上还可以接收异常类型的参数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| static <T, E extends Exception> Consumer<T> handlingConsumerWrapper( ThrowingConsumer<T, E> throwingConsumer, Class<E> exceptionClass) {
return i -> { try { throwingConsumer.accept(i); } catch (Exception ex) { try { E exCast = exceptionClass.cast(ex); System.err.println( "Exception occured : " + exCast.getMessage()); } catch (ClassCastException ccEx) { throw new RuntimeException(ex); } } }; }
|
参考:https://blog.csdn.net/Revivedsun/article/details/79906165