completablefuture.handle 是统一处理成功结果与异常的单次执行方法,接收 bifunction 参数,无论成败均执行一次并返回新 completablefuture 结果。

CompletableFuture.handle 是一个既能捕获正常结果、又能捕获异常的统一处理方法,不需要像 thenApply + exceptionally 那样拆成两路逻辑。
handle 的签名和核心特点
它的函数式接口是:public <u> CompletableFuture<u> handle(BiFunction<t throwable u> fn)</t></u></u>
关键点:
- 接收两个参数:第一个是正常计算结果(成功时非 null),第二个是异常(失败时非 null,成功时为 null)
- 必须返回一个值(不能为 void),这个值会成为新 CompletableFuture 的结果
- 无论原任务成功或失败,
handle中的逻辑都会执行一次,且仅执行一次
典型用法:统一日志 + 转换结果
比如调用一个可能出错的远程接口,希望无论成功失败都记录日志,并返回封装后的响应对象:
CompletableFuture<string> future = CompletableFuture.supplyAsync(() -> {
if (Math.random() > 0.5) throw new RuntimeException("网络超时");
return "success";
});
CompletableFuture<apiresponse> handled = future.handle((result, ex) -> {
if (ex == null) {
System.out.println("✅ 获取成功: " + result);
return new ApiResponse(true, result, null);
} else {
System.err.println("❌ 获取失败: " + ex.getMessage());
return new ApiResponse(false, null, ex.getMessage());
}
});
</apiresponse></string>
注意返回值类型要一致
handle 的泛型 U 是新 CompletableFuture 的元素类型。如果想保持类型不变,就让 BiFunction 返回原类型(或其子类);如果需要兜底默认值,也可以返回替代值:
- 成功时返回
result,失败时返回"default"→ 新 future 类型是CompletableFuture<string></string> - 成功返回
result.toUpperCase(),失败返回"ERROR"→ 同样是String - 不能一半返回
String、一半返回Integer,编译不通过
和 exceptionally / whenComplete 的区别
对比更常用的几个方法:
-
exceptionally(Function<throwable t>)</throwable>:只在异常时触发,且只能返回原类型值,无法访问正常结果 -
whenComplete(BiConsumer<t throwable>)</t>:能同时看到结果和异常,但不改变 future 的结果值(返回CompletableFuture<void></void>的语义) -
handle:既能读又能改,适合做“转换+兜底”类操作
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











