为什么从 try-catch 块内返回 CompletableFuture.completedFuture(...) 会导致此错误?

Why does returning CompletableFuture.completedFuture(...) from inside a try-catch block (appear to) cause this error?

我有一个方法 returns 一个 CompletionStage<> 在不同的点,但似乎从 try-catch 块中这样做会导致“不兼容的类型”错误:

Incompatible types

Required: CompletionStage<com.foo.Response>

Found: CompletableFuture<? extends com.foo.Response>

这是代码。我尽可能地简化了它,而不可能删除罪魁祸首:

  public CompletionStage<Response> example(final Optional<String> idMaybe) {

    return idMaybe.map(id -> {

      if (true) { // Simplified example.

        if (!NumberUtils.isNumber(id)) {
          return CompletableFuture.completedFuture(Response.forStatus(Status.BAD_REQUEST));
        }

        final SomeServiceInterface service;
        try {
          service = someClient.getServiceInterface(SomeServiceInterface.class);
        } catch (SomeException e) {
          LOG.error("Error retrieving SomeServiceInterface.", e);
          return CompletableFuture.completedFuture(Response.forStatus(Status.INTERNAL_SERVER_ERROR));
        }

        final Page page;
        try {
          page = someService.getSomethingByStatement(statementBuilder.toStatement());
        } catch (RemoteException e) {
          LOG.error("Error retrieving a thing by statement", e);
          return CompletableFuture.completedFuture(Response.forStatus(Status.INTERNAL_SERVER_ERROR));
        }

        if (page.getResults() == null || page.getTotalResultSetSize() == 0) {
          return CompletableFuture.completedFuture(Response.forStatus(Status.NOT_FOUND));
        }

        if (page.getTotalResultSetSize() != 1) {
          // There should be only one result.
          return CompletableFuture.completedFuture(Response.forStatus(Status.INTERNAL_SERVER_ERROR));
        }
      }

      return CompletableFuture.completedFuture(Response.ok());

    }).orElse(CompletableFuture.completedFuture(Response.forStatus(Status.BAD_REQUEST)));

  }

为了缩小问题的范围,我将失败案例 return 一个一个地倒退删除。所以首先,删除这个:

        if (page.getTotalResultSetSize() != 1) {
          // There should be only one result.
          return CompletableFuture.completedFuture(Response.forStatus(Status.INTERNAL_SERVER_ERROR));
        }

还是一样的错误。那么,删除这个:

        if (page.getResults() == null || page.getTotalResultSetSize() == 0) {
          return CompletableFuture.completedFuture(Response.forStatus(Status.NOT_FOUND));
        }

还是一样的错误。那么,删除这个:

        final Page page;
        try {
          page = someService.getSomethingByStatement(statementBuilder.toStatement());
        } catch (RemoteException e) {
          LOG.error("Error retrieving a thing by statement", e);
          return CompletableFuture.completedFuture(Response.forStatus(Status.INTERNAL_SERVER_ERROR));
        }

还是一样的错误。那么,删除这个:

        final SomeServiceInterface service;
        try {
          service = someClient.getServiceInterface(SomeServiceInterface.class);
        } catch (SomeException e) {
          LOG.error("Error retrieving SomeServiceInterface.", e);
          return CompletableFuture.completedFuture(Response.forStatus(Status.INTERNAL_SERVER_ERROR));
        }

消除了错误。 (我仔细检查了这不是因为它在其他地方引起了错误;它编译了。)

从 try-catch 块中返回可完成的 future 有什么不同?或者,发生了什么使它看起来如此?我该如何修复原始代码?

我认为@MạnhQuyếtNguyễn 在评论中的想法是正确的,但由于我无法轻松地按照他的方式构建我的代码,我找到了另一个解决方案:

return creativeIdMaybe.<CompletionStage<Response>>map(creativeId -> {

所以毕竟,我认为是 map 解决了类型问题。 (我想。我不知道。)