Lambda表达式 异常处理

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