面试题答案
一键面试-
异常处理方式阐述
- 使用
exceptionally
方法:CompletableFuture
提供了exceptionally
方法,它可以在CompletableFuture
链中的任何一个环节出现异常时捕获并处理异常。该方法接收一个Function
作为参数,这个Function
以抛出的异常为输入,返回一个默认值或者经过处理的值,用于替代出现异常的CompletableFuture
原本应该返回的结果,从而使得异步流能够继续执行下去。 - 使用
whenComplete
或handle
方法:whenComplete
方法可以在CompletableFuture
完成(无论是正常完成还是异常完成)时执行一段代码,它可以用来记录日志等操作。handle
方法类似于whenComplete
,但它可以返回一个新的值,用于替代出现异常时原本应该返回的结果,从而实现恢复逻辑。
- 使用
-
代码实现
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
public class CompletableFutureExceptionHandling {
public static void main(String[] args) {
CompletableFuture.supplyAsync(() -> {
if (Math.random() > 0.5) {
throw new RuntimeException("模拟异常");
}
return "任务1成功";
})
.thenApply(result -> {
System.out.println("任务1结果: " + result);
return "任务2输入: " + result;
})
.thenApplyAsync(result -> {
if (Math.random() > 0.5) {
throw new IllegalArgumentException("另一个模拟异常");
}
return "任务2成功: " + result;
})
.exceptionally(ex -> {
System.out.println("捕获到异常: " + ex.getMessage());
return "异常恢复值";
})
.whenComplete((result, ex) -> {
if (ex != null) {
System.out.println("日志记录 - 异常: " + ex.getMessage());
} else {
System.out.println("日志记录 - 正常结果: " + result);
}
})
.thenAccept(System.out::println);
try {
// 等待所有异步操作完成
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
在上述代码中:
supplyAsync
启动一个异步任务,模拟可能抛出异常的操作。thenApply
和thenApplyAsync
构建异步操作链,同样模拟了可能抛出异常的操作。exceptionally
捕获前面操作抛出的异常,并返回一个恢复值,使得异步流可以继续执行。whenComplete
用于记录日志,根据是否有异常打印不同的信息。thenAccept
用于消费最终的结果(包括异常恢复后的结果)并打印。Thread.sleep
用于等待所有异步操作完成。