Incompatible types: bad return type in lambda expression X cannot be converted to CompetionStage<X>, after adding a layer of thenApply
Incompatible types: bad return type in lambda expression X cannot be converted to CompetionStage<X>, after adding a layer of thenApply
我收到以下错误
[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
是 return 一个 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);
});
}
所以你看,我们正在 return 编辑 .thenApply()
return 或 .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);
});
}
我所做的就是添加另一层.thenApply()
。但我的内部 .thenApply()
return 与原始代码 returning 相同,而我的外部 .thenApply()
只是将其传递。
那么为什么我现在突然收到关于转换为 CompletionStage
的投诉?我试了这个只是为了好玩:
return CompletableFuture.completedFuture(checkExceptionCauses(exception));
毫不奇怪,我现在收到了更高级别的投诉,关于 return 使用 CompletionStage<Response<ByteString>>
而不是 Response<ByteString>
。
thenApply
如果你有同步映射功能就用
根据 Documentation:
Returns a new CompletionStage
that, when this stage completes
normally, is executed with this stage's result as the argument to the
supplied function.
另一方面,如果您有一个 returns 和 CompletableFuture
的异步映射函数,则使用 thenCompose
。换句话说,thenCompose
returns 直接带有结果的未来,而不是嵌套的未来。
来自 Documentation:
Returns a new CompletionStage
that is completed with the same value as
the CompletionStage
returned by the given function.
When this stage completes normally, the given function is invoked with
this stage's result as the argument, returning another
CompletionStage
. When that stage completes normally, the
CompletionStage
returned by this method is completed with the same
value.
所以尝试用thenCompose
替换thenApply
。
我收到以下错误
[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
是 return 一个 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);
});
}
所以你看,我们正在 return 编辑 .thenApply()
return 或 .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);
});
}
我所做的就是添加另一层.thenApply()
。但我的内部 .thenApply()
return 与原始代码 returning 相同,而我的外部 .thenApply()
只是将其传递。
那么为什么我现在突然收到关于转换为 CompletionStage
的投诉?我试了这个只是为了好玩:
return CompletableFuture.completedFuture(checkExceptionCauses(exception));
毫不奇怪,我现在收到了更高级别的投诉,关于 return 使用 CompletionStage<Response<ByteString>>
而不是 Response<ByteString>
。
thenApply
如果你有同步映射功能就用
根据 Documentation:
Returns a new
CompletionStage
that, when this stage completes normally, is executed with this stage's result as the argument to the supplied function.
另一方面,如果您有一个 returns 和 CompletableFuture
的异步映射函数,则使用 thenCompose
。换句话说,thenCompose
returns 直接带有结果的未来,而不是嵌套的未来。
来自 Documentation:
Returns a new
CompletionStage
that is completed with the same value as theCompletionStage
returned by the given function. When this stage completes normally, the given function is invoked with this stage's result as the argument, returning anotherCompletionStage
. When that stage completes normally, theCompletionStage
returned by this method is completed with the same value.
所以尝试用thenCompose
替换thenApply
。