Функция, которую вы передаете 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);
}