thenApply 是 CompletableFuture 的同步结果转换方法,成功时用 Function<T,R> 映射前任务结果为新 CompletableFuture<R>,在原线程执行、不处理异常、不支持阻塞操作。

thenApply 是 CompletableFuture 提供的同步结果转换方法,它在前一个异步任务**成功完成**后,用指定函数处理其返回值,并将处理结果作为新 CompletableFuture 的结果。它不改变执行线程(默认在前一个任务结束的线程上执行),也不处理异常。
核心行为:结果映射,不改变执行上下文
它类似 Stream 的 map,只做“值到值”的转换:
- 输入:前一个
CompletableFuture<T>的成功结果(类型 T) - 操作:你传入的
Function<T, R>函数(例如把 String 转成 Integer、把 User 对象转成 DTO) - 输出:新的
CompletableFuture<R>,结果是函数执行后的值(类型 R) - 若上游失败(抛异常),
thenApply不触发,下游 future 也以相同异常完成
典型用法示例
假设有一个查用户 ID 的异步方法,你想把它转成用户详情对象:
CompletableFuture<String> userIdFuture = CompletableFuture.supplyAsync(() -> "123");
CompletableFuture<User> userFuture = userIdFuture.thenApply(id -> {
// 这里同步执行:根据 ID 查询并构造 User 对象
return new User(id, "张三", 28);
});
注意:thenApply 内部的逻辑是同步执行的,不要在里面写阻塞 I/O 或耗时计算;如需异步调用(比如再发一次 HTTP 请求),应改用 thenCompose 或 thenApplyAsync。
立即学习“Java免费学习笔记(深入)”;
和 thenApplyAsync 的关键区别
-
thenApply:在上游任务完成的**同一个线程**中执行转换函数(轻量、低开销) -
thenApplyAsync:提交到 ForkJoinPool.commonPool()(或自定义 Executor)中异步执行,适合含 CPU 密集型或需解耦线程场景
链式转换与类型演进
可连续调用多次 thenApply,实现多步数据加工:
CompletableFuture<String> jsonFuture = CompletableFuture.completedFuture("{\"name\":\"李四\"}");
CompletableFuture<Map<String, Object>> mapFuture = jsonFuture
.thenApply(Json::parseString) // String → Map
.thenApply(data -> Collections.unmodifiableMap(data)); // Map → ImmutableMap
每一步都生成新 future,类型随函数返回值自动推导,编译期强类型安全。


















