函数可完成的未来与gradle不兼容的错误

时间:2018-06-06 11:18:46

标签: java gradle java-8 executorservice completable-future

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

如何纠正这个问题?

1 个答案:

答案 0 :(得分:0)

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

这意味着handle()的结果因此是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);
}