与 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());

如何纠正?

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

这意味着handle()的结果因此是一个CompletableFuture<CompletableFuture<?>>,你试图使用传递给thenCompose()的恒等函数来解包。

这意味着您尝试将此结果分配给future应声明为CompletableFuture<?>

执行此操作后,不幸的是,仍然无法将identity()用于组合,因为编译器无法推断此调用的正确泛型类型,并选择超出强制转换预期范围的默认Object,或者如果删除它,则会thenCompose()

另一方面,如果您尝试通过以下方式强制实施实际类型:

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

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

但是,这个问题有一个简单的解决方法:只需使用 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);
}

最新更新