CompletableFuture 异常:恢复值和观察错误要区分
异步调用失败后,有的方法会把异常转成默认值,有的方法仅观察结果。混用会让上层误以为失败已经被正确处理。
问题从哪里出现
异步调用失败后,有的方法会把异常转成默认值,有的方法仅观察结果。混用会让上层误以为失败已经被正确处理。
理解核心机制
exceptionally 可以提供恢复值,whenComplete 用于观察成功或失败但通常不替换结果。join 会以 CompletionException 包装失败;链路中每一步都应明确异常是否继续传播。
动手做一个小实验
Java 17 或更新版本;将示例保存为 Demo.java,执行 javac Demo.java 后运行 java Demo。
import java.util.concurrent.CompletableFuture;
public class Demo {
public static void main(String[] args) {
var result = CompletableFuture.<String>failedFuture(
new IllegalStateException("upstream unavailable"))
.exceptionally(error -> "cached-value");
System.out.println(result.join());
}
}适用边界与常见误区
用默认值掩盖故障可能损害数据正确性。超时的 Future 完成方式与底层任务是否真正停止也不是同一件事。
继续练习
把 exceptionally 改成 whenComplete,观察 join 的行为;为业务定义哪些失败允许返回缓存。