CompletableFuture通过exceptionally、handle和whenComplete方法实现异步异常处理:exceptionally仅在失败时提供备用结果,handle统一处理成功与失败并可转换结果,whenComplete则用于执行日志等副作用而不改变状态。

在Java中,
CompletableFuture
try-catch
CompletableFuture
exceptionally(Function<Throwable, T> fn)
catch
CompletableFuture
fn
fn
CompletableFuture
CompletableFuture
exceptionally
CompletableFuture
handle(BiFunction<T, Throwable, R> fn)
try-catch-finally
fn
CompletableFuture
fn
T
null
Throwable
null
Throwable
CompletableFuture
立即学习“Java免费学习笔记(深入)”;
whenComplete(BiConsumer<T, Throwable> action)
action
exceptionally
handle
whenComplete
CompletableFuture
CompletableFuture
whenComplete
exceptionally
handle
在链中显式返回失败的 CompletableFuture
thenApply
thenCompose
CompletableFuture.failedFuture(new Exception("..."))以下是一些代码示例,展示了这些方法的实际应用:
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
public class CompletableFutureExceptionHandling {
public static void main(String[] args) throws InterruptedException {
System.out.println("--- 示例 1: 使用 exceptionally() ---");
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {
if (ThreadLocalRandom.current().nextBoolean()) {
throw new RuntimeException("任务 1 出错了!"); // 模拟随机失败
}
return "任务 1 的结果";
}).exceptionally(ex -> {
System.err.println("exceptionally 捕获到异常 (任务 1): " + ex.getMessage());
return "任务 1 的备用结果"; // 提供一个备用值
});
future1.thenAccept(result -> System.out.println("任务 1 最终结果: " + result));
System.out.println("\n--- 示例 2: 使用 handle() ---");
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {
if (ThreadLocalRandom.current().nextBoolean()) {
throw new IllegalStateException("任务 2 因状态问题失败!"); // 模拟随机失败
}
return "任务 2 的结果";
}).handle((result, ex) -> {
if (ex != null) {
System.err.println("handle 捕获到异常 (任务 2): " + ex.getMessage());
return "任务 2 的处理后备用结果"; // 将失败转换为成功,并提供信息
}
return result + " (成功处理)"; // 成功时也进行转换
});
future2.thenAccept(result -> System.out.println("任务 2 最终结果: " + result));
System.out.println("\n--- 示例 3: 使用 whenComplete() 进行副作用操作 ---");
CompletableFuture<String> future3 = CompletableFuture.supplyAsync(() -> {
if (ThreadLocalRandom.current().nextBoolean()) {
throw new ArithmeticException("任务 3 发生算术错误!"); // 模拟随机失败
}
return "任务 3 的结果";
}).whenComplete((result, ex) -> {
if (ex != null) {
System.err.println("副作用: 任务 3 失败,异常信息: " + ex.getMessage());
} else {
System.out.println("副作用: 任务 3 成功完成,结果: " + result);
}
}).exceptionally(ex -> { // whenComplete 不改变状态,如果需要处理失败,仍需 exceptionally 或 handle
System.err.println("whenComplete 后捕获异常 (任务 3): " + ex.getMessage());
return "任务 3 的最终备用结果";
});
future3.thenAccept(result -> System.out.println("任务 3 最终结果: " + result));
System.out.println("\n--- 示例 4: 链式调用中传播失败 ---");
CompletableFuture<Integer> future4 = CompletableFuture.supplyAsync(() -> {
System.out.println("开始执行任务 4");
if (true) { // 强制失败,用于演示
throw new RuntimeException("任务 4 强制失败");
}
return 10;
}).thenApply(data -> { // 如果上一步失败,这一步不会执行
System.out.println("任务 4 正在处理数据: " + data);
return data * 2;
}).exceptionally(ex -> {
System.err.println("任务 4 链中捕获异常: " + ex.getMessage());
return -1; // 提供一个错误值
});
future4.thenAccept(val -> System.out.println("任务 4 最终值: " + val));
// 等待所有异步任务完成,以便观察输出
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}exceptionally()
handle()
whenComplete()
这三者是
CompletableFuture
exceptionally()
CompletableFuture
exceptionally()
Future
Future
handle()
CompletableFuture
handle()
null
handle()
whenComplete()
whenComplete()
CompletableFuture
Future
whenComplete()
Future
whenComplete()
简而言之:
exceptionally()
handle()
whenComplete()
CompletableFuture
在
CompletableFuture
要避免这种情况,我认为有几个关键点:
首先,务必记录原始异常。无论你使用
exceptionally()
handle()
Throwable
exceptionally(ex -> { log.error("Async task failed", ex); return "default"; })exceptionally(ex -> "default")
其次,谨慎选择异常处理策略。如果你在
exceptionally()
handle()
null
null
NullPointerException
CompletableFuture.failedFuture(new MyBusinessException("..."))再者,理解 join()
get()
CompletableFuture
join()
get()
CompletableFuture
CompletionException
ExecutionException
以上就是如何在Java中使用CompletableFuture处理异常的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号