首页 > 解决方案 > 为什么从 try-catch 块(似乎)返回 CompletableFuture.completedFuture(...) 会导致此错误?

问题描述

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

不兼容的类型

必需:CompletionStage<com.foo.Response>

发现:CompletableFuture<? 扩展 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 块中返回一个可完成的未来有什么不同?或者,发生了什么让它看起来如此?以及如何修复原始代码?

标签: javacompiler-errorstry-catchtype-inferencecompletable-future

解决方案


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

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

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


推荐阅读