Несовместимая ошибка с gradle для функций Completable Future - PullRequest
0 голосов
/ 06 июня 2018
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");
}

Этот фрагмент кода работает нормально на затмении, но когда я собираюсь строить с использованием gradle, ошибка его выдачи:

несовместимые типы: Function<Object,Object> невозможно преобразовать в Function<? super CompletableFuture<? extends Object>,? extends CompletionStage<Void>>.identity());

как это исправить?

1 Ответ

0 голосов
/ 06 июня 2018

Функция, которую вы передаете handle(), может возвращать либо CompletableFuture<Throwable>, либо CompletableFuture<Void>.Таким образом, единственным совместимым типом является CompletableFuture<?>.

. Это означает, что результатом handle() является, таким образом, CompletableFuture<CompletableFuture<?>>, который вы пытаетесь развернуть, используя функцию идентификации, переданную в thenCompose().

Это означает, что future, которому вы пытаетесь присвоить этот результат, должен быть объявлен как CompletableFuture<?>.

Как только вы это сделаете, к сожалению, все еще невозможно использовать identity() длякомпозиции, поскольку компилятор не может определить правильный универсальный тип для этого вызова и выбирает значение по умолчанию Object, выходящее за пределы, ожидаемые приведением, или значение thenCompose(), если вы его удалите.

Вкл.с другой стороны, если вы попытаетесь применить фактический тип с помощью:

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

, то компилятор все еще не сможет определить переменную типа U из thenCompose(), что тоже не помогает.

Однако, есть простой обходной путь для этой проблемы: просто используйте лямбда-выражение:

.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);
}
...