首页 > 解决方案 > Functions Completable Future 上的 gradle 不兼容错误

问题描述

public void initateScheduledRequest(long time, Runnable actionRequired) {
    LOGGER.info("Retry Request Initated");
    ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor();
    Executor timeDiff = r -> ses.schedule(() -> executor.execute(r), time, TimeUnit.SECONDS);
    CompletableFuture<Void> future = CompletableFuture.runAsync(actionRequired, executor);
    for (int i = 0; i < 3; i++) {
        future = future
                .handle((k, v) -> v == null ? CompletableFuture.completedFuture(v)
                        : CompletableFuture.runAsync(actionRequired, timeDiff))
                .thenCompose(
                         (Function<? super CompletableFuture<? extends Object>, ? extends CompletionStage<Void>>) Function
                                .identity());
    }
    LOGGER.info("Retry Done");
}

这段代码在 Eclipse 上运行良好,但是当我要使用 gradle 构建时,它会给出错误:

不兼容的类型:Function<Object,Object>不能转换为 Function<? super CompletableFuture<? extends Object>,? extends CompletionStage<Void>>.identity());

如何纠正这个?

标签: javagradlejava-8executorservicecompletable-future

解决方案


您传递给的函数handle()可以返回 aCompletableFuture<Throwable>或 a CompletableFuture<Void>。唯一兼容的类型是因此CompletableFuture<?>

这意味着 的结果handle()因此是 a CompletableFuture<CompletableFuture<?>>,您正试图使用​​传递给 的标识函数对其进行解包thenCompose()

这意味着future您尝试分配此结果的对象应声明为CompletableFuture<?>.

一旦你这样做了,不幸的是仍然不能identity()用于组合,因为编译器无法为这个调用推断正确的泛型类型并选择Object超出强制转换预期范围的默认值,或者thenCompose()如果你删除它.

另一方面,如果您尝试使用以下命令强制执行实际类型:

.thenCompose(Function.<CompletableFuture<?>>identity());

然后编译器仍然无法推断出也无济于事的类型U变量thenCompose()

但是,有一个简单的解决方法来解决这个问题:只需使用 lambda 表达式:

.thenCompose(f -> f)

所以生成的代码将是:

CompletableFuture<?> future = CompletableFuture.runAsync(actionRequired, executor);
for (int i = 0; i < 3; i++) {
    future = future
            .handle((k, v) -> v == null ? CompletableFuture.completedFuture(v)
                    : CompletableFuture.runAsync(actionRequired, timeDiff))
            .thenCompose(f -> f);
}

推荐阅读