面试题答案
一键面试- 使用
exceptionally
方法- 代码示例:
CompletableFuture.supplyAsync(() -> {
if (Math.random() < 0.5) {
throw new RuntimeException("模拟异常");
}
return "任务正常完成";
}).exceptionally(ex -> {
System.out.println("捕获到异常: " + ex.getMessage());
return "默认值";
}).thenAccept(System.out::println);
- 处理方式:
exceptionally
方法会在CompletableFuture
出现异常时被调用,它接收一个Function
,该Function
的输入为异常对象,返回值是在出现异常时要返回的替代结果。 - 特点:它主要用于在异常发生时提供一个备用的结果,适用于需要在异常时返回一个特定值的场景。
- 使用
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);
}
});
- 处理方式:
whenComplete
方法接收一个BiConsumer
,无论CompletableFuture
正常完成还是出现异常,都会调用这个BiConsumer
。BiConsumer
的第一个参数是任务正常完成的结果(如果有异常则为null
),第二个参数是异常对象(如果任务正常完成则为null
)。 - 特点:它更侧重于对任务完成状态(包括异常情况)的统一处理,不返回新的结果,只是在任务完成(正常或异常)后执行一些操作,比如记录日志等。
- 使用
handle
方法- 代码示例:
CompletableFuture.supplyAsync(() -> {
if (Math.random() < 0.5) {
throw new RuntimeException("模拟异常");
}
return "任务正常完成";
}).handle((result, ex) -> {
if (ex != null) {
System.out.println("捕获到异常: " + ex.getMessage());
return "默认值";
}
return result;
}).thenAccept(System.out::println);
- 处理方式:
handle
方法接收一个BiFunction
,与whenComplete
类似,无论任务正常完成还是出现异常都会调用。BiFunction
的第一个参数是任务正常完成的结果(如果有异常则为null
),第二个参数是异常对象(如果任务正常完成则为null
)。handle
方法会返回一个新的CompletableFuture
,其结果由BiFunction
的返回值决定。 - 特点:它既可以像
exceptionally
一样在异常时返回备用结果,又能像whenComplete
那样对任务的正常和异常情况进行统一处理,灵活性较高。
区别总结:
exceptionally
专注于异常时提供备用结果。whenComplete
侧重于任务完成状态的统一处理,不返回新结果。handle
兼具二者特点,既处理任务状态又能返回新结果,灵活性强。