Почему этот код CompletionStage вызывает ошибку компиляции?

У меня есть два класса, скажем, A и B; оба возвращают CompletionStage.
код класса B:

class B {
    public CompletionStage<Optional<Map<String, Object>>> m1(SampleObject1 obj) {
        return CompletableFuture.supplyAsync(() -> dosomething(obj))
            .thenApplyAsync(results ->
                Optional.ofNullable((results.length == 1) ? results : null)
            );
    }
}

код класса А:

class A {
    public CompletionStage<Optional<SampleObject2>> m2(Optional<DynamicForm> dynamicForm) {
        CompletionStage<DynamicForm> promiseOfFormData = CompletableFuture.supplyAsync(() -> dynamicForm.get());

        CompletionStage<Optional<Map<String, Object>>> c = promiseOfFormData.thenApplyAsync(
            data -> b.m1(new SampleObject1(data.get("key1"), data.get("key2")))
        );
        return something.....;
    }
}

Тем не менее, он выдает следующую ошибку во время выполнения:

inference variable U has incompatible bounds
    equality constraints: java.util.Optional<java.util.Map<java.lang.String,java.lang.Object>>
    lower bounds: java.util.concurrent.CompletionStage<java.util.Optional<java.util.Map<java.lang.String,java.lang.Object>>>

Что я здесь не так делаю?

1 ответ

Решение

У вас есть проблема с вашими типами возврата:

b.m1(new SampleObject1(data.get("key1"), data.get("key2")))

возвращает CompletionStage<Optional<Map<String, Object>>> как из сигнатуры метода в B, так

data -> b.m1(new SampleObject1(data.get("key1"), data.get("key2")))

имеет тип Function<DynamicForm,CompletionStage<Optional<Map<String, Object>>>> и следующее

promiseOfFormData.thenApplyAsync(
    data -> b.m1(new SampleObject1(data.get("key1"), data.get("key2")))
);

таким образом, имеет тип CompletionStage<CompletionStage<Optional<Map<String, Object>>>> который несовместим с целевым типом CompletionStage<Optional<Map<String, Object>>>, У вас ошибка в вычислении границ целевого типа.

Что вы должны сделать вместо этого, вероятно, использовать CompletionStage#thenComposeAsync, который предназначен для функций, которые также возвращают CompletionStage:

CompletionStage<Optional<Map<String, Object>>> c = promiseOfFormData.thenComposeAsync(
    data -> b.m1(new SampleObject1(data.get("key1"), data.get("key2")))
);

В качестве альтернативы, вы можете переписать m1 не создавать CompletionStage но просто выполнить вычисление, а затем использовать его в thenApplyAsync звоните, как раньше.

Другие вопросы по тегам