You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

继承CompletableFuture后supplyAsync无法返回Promise<T>的问题

解决Java中继承CompletableFuture后静态方法返回类型不匹配问题

问题描述

想要实现JS风格的Promise工具类,通过继承CompletableFuture复用其异步能力,但调用静态方法supplyAsync时无法直接得到Promise<T>实例:直接赋值会报类型不匹配错误,强转则触发ClassCastException。

原代码

import java.util.concurrent.CompletableFuture;

class Main {
    public static class Promise<T> extends CompletableFuture<T>{}
    
    public static void main(String[] args) {
        System.out.println(System.getProperty("java.version"));
        // 正常工作:返回CompletableFuture<String>
        CompletableFuture<String> p1 = Promise.supplyAsync(() -> "foobar");
        // 无法工作,但需要返回Promise<String>
        Promise<String> p2 = Promise.supplyAsync(() -> "foobar");
    }
}

错误信息

直接赋值时的编译错误:

ERROR!
/tmp/kpS1aJoUkj/Main.java:13: error: incompatible types: no instance(s) of type variable(s) U exist so that CompletableFuture<U> conforms to Promise<String>
        Promise<String> p2 = Promise.supplyAsync(() -> {
                                                ^
  where U is a type-variable:
    U extends Object declared in method <U>supplyAsync(Supplier<U>)
1 error

强转后的运行时错误:

ERROR!
Exception in thread "main" java.lang.ClassCastException: class java.util.concurrent.CompletableFuture cannot be cast to class Main$Promise (java.util.concurrent.CompletableFuture is in module java.base of loader 'bootstrap'; Main$Promise is in unnamed module of loader 'app')
    at Main.main(Main.java:13)

解决方案

CompletableFuture的静态工厂方法(如supplyAsync)返回的是自身类的实例,而非子类Promise的实例。因此需要在Promise类中封装静态方法,手动创建Promise实例并同步父类异步任务的结果。

修改后的代码

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.function.Supplier;

class Main {
    public static class Promise<T> extends CompletableFuture<T> {
        // 无参线程池版本的supplyAsync
        public static <U> Promise<U> supplyAsync(Supplier<U> supplier) {
            Promise<U> promise = new Promise<>();
            // 调用父类的supplyAsync,监听结果并同步到Promise实例
            CompletableFuture.supplyAsync(supplier)
                .whenComplete((result, throwable) -> {
                    if (throwable != null) {
                        promise.completeExceptionally(throwable);
                    } else {
                        promise.complete(result);
                    }
                });
            return promise;
        }

        // 自定义线程池版本的supplyAsync
        public static <U> Promise<U> supplyAsync(Supplier<U> supplier, Executor executor) {
            Promise<U> promise = new Promise<>();
            CompletableFuture.supplyAsync(supplier, executor)
                .whenComplete((result, throwable) -> {
                    if (throwable != null) {
                        promise.completeExceptionally(throwable);
                    } else {
                        promise.complete(result);
                    }
                });
            return promise;
        }
    }

    public static void main(String[] args) {
        System.out.println(System.getProperty("java.version"));
        // 现在可以正常获取Promise实例
        Promise<String> p2 = Promise.supplyAsync(() -> "foobar");
        // 测试异步结果
        p2.thenAccept(System.out::println);
    }
}

原理说明

  • 父类CompletableFuture的静态方法不会自动返回子类实例,直接调用Promise.supplyAsync实际是继承父类的方法,返回CompletableFuture对象,因此无法直接赋值给Promise变量。
  • 封装后的静态方法通过创建Promise实例,监听父类异步任务的完成状态,将结果或异常同步到Promise实例中,确保返回的是Promise类型的对象,满足JS风格工具类的需求。

内容的提问来源于stack exchange,提问作者Dan D

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 09:25:11