面试题答案
一键面试异常处理机制区别
- exceptionally:主要用于捕获并处理
CompletableFuture
执行过程中抛出的异常。它接收一个Function
作为参数,该Function
的输入为异常,返回值为当异常发生时的替代结果。如果CompletableFuture
正常完成,exceptionally
方法不会执行。 - whenComplete:无论
CompletableFuture
正常完成还是发生异常,都会执行。它接收一个BiConsumer
作为参数,该BiConsumer
的两个参数分别为任务结果(如果正常完成)和异常(如果发生异常)。但是whenComplete
不能改变任务的最终结果,它只是用于执行一些最终的操作,如日志记录等。
使用场景区别
- exceptionally:适用于需要在异常发生时提供一个替代结果的场景,比如在远程调用失败时返回一个本地缓存的数据。
- whenComplete:适用于无论任务成功或失败都需要执行一些通用操作的场景,比如记录任务执行的状态和结果。
对任务结果处理方式区别
- exceptionally:可以返回一个新的结果来替代异常情况下的原结果,改变任务的最终输出。
- whenComplete:不能改变任务的最终结果,只是在任务结束时进行一些额外操作。
代码示例对比
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
public class CompletableFutureExceptionHandling {
public static void main(String[] args) {
// 使用exceptionally方法
CompletableFuture.supplyAsync(() -> {
if (Math.random() < 0.5) {
throw new RuntimeException("模拟异常");
}
return "正常结果";
}).exceptionally(ex -> {
System.out.println("捕获到异常: " + ex.getMessage());
return "异常替代结果";
}).thenAccept(System.out::println);
// 使用whenComplete方法
CompletableFuture.supplyAsync(() -> {
if (Math.random() < 0.5) {
throw new RuntimeException("模拟异常");
}
return "正常结果";
}).whenComplete((result, ex) -> {
if (ex != null) {
System.out.println("捕获到异常: " + ex.getMessage());
} else {
System.out.println("正常结果: " + result);
}
}).thenApply(result -> {
// 这里不能改变最终结果,因为whenComplete不能改变任务结果
return result;
}).thenAccept(System.out::println);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
在上述代码中,exceptionally
方法在异常发生时返回了替代结果并打印。whenComplete
方法只是打印了任务的状态(正常或异常),不能改变任务最终结果。