代码之家  ›  专栏  ›  技术社区  ›  Andrew Cheong

不兼容的类型:lambda表达式X中的错误返回类型在添加thenApply层后无法转换为CompetionStage

  •  1
  • Andrew Cheong  · 技术社区  · 8 年前

    我得到以下错误

    [ERROR] AccountServiceResource.java:[165,38] incompatible types: bad return type in lambda expression
    [ERROR] Response<okio.ByteString> cannot be converted to java.util.concurrent.CompletionStage<Response<okio.ByteString>>
    

    关于以下行

    return checkExceptionCauses(exception);
    

    哪里 checkedExceptionCauses 是一个返回 Response<ByteString>

    private Response<ByteString> checkExceptionCauses(Throwable exception) {
         // ...
    }
    

    问题是,为什么它试图将其转换为 CompletionStage<> 突然地以下是编译得很好的原始代码(简化版):

    private CompletionStage<Response<ByteString>> getAccountById(RequestContext rc) {
        return accountServiceClient.getAccount().thenApply( getAccountResponse -> {
          AdAccountResponse payload;
          payload.map(getAccountResponse);
          return Response.forPayload(serializePayload(payload));
        }).exceptionally(exception -> {
          LOG.error("Lorem ipsum");
          return checkExceptionCauses(exception);
        });
    }
    

    所以你看,我们返回了 .thenApply() 返回,或 .exceptionally() (无可否认,我不太熟悉可完成的未来,所以这可能就是我在这里感到困惑的原因。)

    但好吧,我觉得我的修改做了同样的事情:

    private CompletionStage<Response<ByteString>> getAccountById(RequestContext rc) {
        return accountServiceClient.getAccount().thenApply( getAccountResponse -> {
          AdAccountResponse payload;
          payload.map(getAccountResponse);
    
          // *** BEGIN CHANGES *** //
          Request salesforceRequest = Request.forUri(FORCEIT_GET_BUSINESS_INFO_URI, "GET").withPayload(businessInfoRequestPayload);
          return httpClient.send(salesforceRequest, rc).thenApply(salesforceResponse -> {
            if (salesforceResponse.payload().isPresent()) {
              // ...
            } else {
              // ...
            }
            AdAccountResponse payload;
            payload.map(getAccountResponse);
            return Response.forPayload(serializePayload(payload));
          });
          // *** END CHANGES *** //
    
        }).exceptionally(exception -> {
          LOG.error("Lorem ipsum");
          return checkExceptionCauses(exception);
        });
    }
    

    我所做的就是添加另一层 .然后应用() .但我有我的内心 .然后应用() 返回与原始代码返回的内容相同的内容 .然后应用() 就这样放弃吧。

    那么,为什么我现在突然收到了关于转换为 CompletionStage ?我试过这个只是为了好玩:

    return CompletableFuture.completedFuture(checkExceptionCauses(exception));
    

    毫不奇怪,我现在接到上级关于退回 CompletionStage<Response<ByteString>> 而不是 响应(<ByteString>

    1 回复  |  直到 8 年前
        1
  •  1
  •   Yahya    8 年前

    thenApply

    根据 Documentation :

    返回一个新的 CompletionStage 当这个阶段结束时 通常,将此阶段的结果作为 提供的功能。

    另一方面 thenCompose 如果有一个异步映射函数返回 CompletableFuture 换句话说, 然后合成 直接返回带有结果的未来,而不是嵌套的未来。

    从…起 Documentation :

    返回一个新的 完成阶段 以与相同的值完成 这个 完成阶段 由给定函数返回。 当此阶段正常完成时,将使用调用给定函数 此阶段的结果作为参数,返回另一个 完成阶段 。当该阶段正常完成时 完成阶段 此方法返回的 相同的 价值

    因此,尝试替换 然后应用 通过 然后合成