面试题答案
一键面试1. 统一异常处理
在链式调用的末尾使用exceptionally
方法来捕获整个链条中的异常,这样可以避免在每个阶段都重复写异常处理代码,提高代码可读性和可维护性。
CompletableFuture.supplyAsync(() -> {
// 模拟可能抛出异常的任务
if (Math.random() > 0.5) {
throw new RuntimeException("任务1异常");
}
return "任务1结果";
})
.thenApply(result -> {
// 模拟结果转换
return result + " 转换后";
})
.exceptionally(ex -> {
// 统一处理异常
System.err.println("捕获到异常: " + ex.getMessage());
return "默认值";
})
.thenAccept(System.out::println);
2. 针对特定阶段处理异常
如果某些阶段的异常需要特殊处理,可以在该阶段使用handle
方法。handle
方法可以同时处理正常结果和异常情况。
CompletableFuture.supplyAsync(() -> {
// 模拟可能抛出异常的任务
if (Math.random() > 0.5) {
throw new RuntimeException("任务1异常");
}
return "任务1结果";
})
.handle((result, ex) -> {
if (ex != null) {
// 处理任务1的异常
System.err.println("任务1异常: " + ex.getMessage());
return "任务1异常默认值";
}
return result;
})
.thenApply(result -> {
// 模拟结果转换
return result + " 转换后";
})
.thenAccept(System.out::println);
3. 使用自定义异常类
定义特定业务场景的异常类,这样在异常处理时可以更明确地知道异常类型,便于针对性处理。
class CustomBusinessException extends RuntimeException {
public CustomBusinessException(String message) {
super(message);
}
}
CompletableFuture.supplyAsync(() -> {
// 模拟可能抛出自定义异常的任务
if (Math.random() > 0.5) {
throw new CustomBusinessException("自定义业务异常");
}
return "任务1结果";
})
.exceptionally(ex -> {
if (ex instanceof CustomBusinessException) {
// 处理自定义业务异常
System.err.println("自定义业务异常: " + ex.getMessage());
return "自定义业务异常默认值";
}
return "其他异常默认值";
})
.thenAccept(System.out::println);
4. 避免异常处理代码冗余
避免在每个thenApply
、thenCompose
等方法中都写类似的异常处理代码。尽可能将通用的异常处理逻辑放在exceptionally
或handle
中,减少冗余。
通过以上几种方式,可以在复杂的CompletableFuture链式调用场景下,优化异常处理,提高代码的可读性、可维护性和性能。