在 completionstage 的链式调用中,failedfuture 方法用于立即返回一个包含异常的状态。要使用函数式接口(如 function),通常是在 exceptionallyasync 或 handleasync 等回调方法中捕获异常并处理。核心做法是:当上游阶段失败时,通过传入一个接受 throwable 并返回新 completionstage 的函数式接口实例,来定义失败后的恢复逻辑或错误传播行为。

如何使用 exceptionallyAsync 处理失败
exceptionallyAsync 接收一个 Function 类型的参数。当上游任务抛出异常时,该函数会被调用,其返回值必须是一个新的 CompletionStage。如果返回的是正常值包装的 Stage,则后续流程继续;如果返回的是失败 Stage,则异常继续传递。

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
public class Main {
public static void main(String[] args) {
CompletableFuture<string> stage = CompletableFuture.supplyAsync(() -> {
throw new RuntimeException("Simulated Error");
});
CompletionStage<string> recovered = stage.exceptionallyAsync(ex -> {
// ex is the Throwable from upstream
return CompletableFuture.completedFuture("Recovered: " + ex.getMessage());
});
System.out.println(recovered.toCompletableFuture().join());
}
}</string></string>
预期输出:
Recovered: Simulated Error
如何在 handleAsync 中结合 failedFuture
handleAsync 接收一个 BiFunction。虽然它不直接返回 CompletionStage,但可以在其中判断是否有异常,并手动构建失败的 CompletionStage 或通过返回特定值影响后续流。若需显式创建失败状态,可使用 CompletableFuture.failedFuture() 静态方法(Java 9+)或在回调中返回一个已完成的失败 Future。

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
public class Main {
public static void main(String[] args) {
CompletableFuture<string> stage = CompletableFuture.supplyAsync(() -> {
throw new IllegalArgumentException("Bad Input");
});
CompletionStage<string> handled = stage.handleAsync((result, ex) -> {
if (ex != null) {
// Create a failed future explicitly
return CompletableFuture.<string>failedFuture(new IllegalStateException("Wrapped", ex)).join();
}
return result;
});
try {
System.out.println(handled.toCompletableFuture().join());
} catch (Exception e) {
System.out.println("Caught: " + e.getCause().getMessage());
}
}
}</string></string></string>
预期输出:
Caught: Wrapped
当输入为 null 时 exception 参数如何处理
在 exceptionallyAsync 和 handleAsync 中,如果上游没有发生异常,Throwable 参数将为 null。此时函数式接口的实现应确保不尝试访问 ex.getMessage() 或类似操作,否则可能引发 NullPointerException。正确的做法是先检查 ex == null,再决定是返回成功结果还是忽略异常分支。
,
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











