继承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
相关产品推荐
相关产品推荐

