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

时间:2018-05-18 17:03:54

标签: java compiler-errors try-catch type-inference completable-future

我有一个方法在不同的点返回CompletionStage<>,但似乎从try-catch块中执行此操作会导致“不兼容的类型”错误:

  

不兼容的类型

     

必需:CompletionStage&lt; com.foo.Response&gt;

     

发现:CompletableFuture&lt;?扩展com.foo.Response&gt;

这是代码。我尽可能地简化了它,但没有消除罪魁祸首:

  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块中返回可完成的未来有何不同?或者,正在发生什么使它看起来如此?我该如何修复原始代码?

1 个答案:

答案 0 :(得分:0)

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

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

毕竟,我认为map解决了这个类型的问题。 (我想。我不知道。)