handle用于统一处理成功与异常并可转换结果类型,whencomplete仅执行日志等副作用操作且不改变结果,exceptionally专用于异常时提供同类型兜底值。

handle 和 whenComplete 都在任务完成(无论成功或失败)后触发,但它们的设计目的和行为有本质区别:handle 用于转换结果(可修改返回值),whenComplete 仅用于副作用操作(不改变结果)。
handle:统一处理并返回新结果
它接收两个参数:正常结果(可能为 null)和异常对象(可能为 null),必须返回一个值,这个值会成为整个 CompletableFuture 的最终结果。
- 如果任务成功,exc 为 null,你可以对 result 做加工或校验,再返回新值
- 如果任务失败,result 为 null,exc 不为 null,你可以捕获异常、记录日志,并返回兜底值(如默认对象、空值、重试结果等)
- 适合做“结果标准化”——比如把异常转成空用户、把 null 金额转成 BigDecimal.ZERO
whenComplete:只执行动作,不改变结果
它也接收 result 和 exc,但方法签名是 BiConsumer<t throwable></t>,没有返回值。它不会影响 CompletableFuture 的原始结果状态。
- 常用于日志记录、指标上报、资源清理等“旁路操作”
- 即使你在回调里抛出新异常,也不会覆盖原任务的完成状态;原 future 仍保持原有成功/失败结果
- 注意:whenComplete 在当前任务所在线程中同步执行;若需异步执行(避免阻塞上游线程),用
whenCompleteAsync并传入线程池
exceptionally:专用于异常兜底
它是 handle 的简化版,只在任务失败时调用,参数只有 Throwable,且必须返回一个替代值。
- 不能处理成功结果,也不能访问正常返回值
- 语义更清晰:纯粹“出错了给我一个默认值”
- 例如:
.exceptionally(e -> User.defaultGuest())
怎么选?看你要不要改结果
想统一收口、做结果映射或异常降级 → 用 handle
只想打日志、发通知、关连接 → 用 whenComplete
只关心失败时给个默认值,其他不管 → 用 exceptionally
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











