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 构建时,出现错误:
incompatible types:
Function<Object,Object>
cannot be converted toFunction<? super CompletableFuture<? extends Object>,? extends CompletionStage<Void>>.identity())
;
如何解决这个问题?
最佳答案
您传递给 handle()
的函数可以返回 CompletableFuture<Throwable>
或 CompletableFuture<Void>
.因此唯一兼容的类型是 CompletableFuture<?>
.
这意味着 handle()
的结果因此是 CompletableFuture<CompletableFuture<?>>
,您正尝试使用传递给 thenCompose()
的标识函数来解开它.
这意味着 future
您尝试将此结果分配给的对象应声明为 CompletableFuture<?>
.
一旦你这样做,不幸的是仍然无法使用 identity()
对于组合,因为编译器无法推断此调用的正确泛型类型并选择默认值 Object
这超出了 Actor 的预期范围,或者是 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);
}
关于java - 函数 Completable Future 上的 gradle 不兼容错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50719121/