无法调用 toCompletableFuture(),因为在使用返回 CompletionStage<Void 的方法时,apply(Object) 的返回值为 null>

Cannot invoke toCompletableFuture() because the return value of apply(Object) is null while working with method that returns CompletionStage<Void>

提问人:Andrew Cheong 提问时间:8/7/2023 更新时间:8/7/2023 访问量:265

问:

我卡在一个错误上:

java.util.concurrent.CompletionException:java.lang.NullPointerException:无法调用“java.util.concurrent.CompletionStage.toCompletableFuture()”,因为“java.util.function.Function.apply(Object)”的返回值为空

错误指向的行如下所示:

.handle(
    (result, ex) -> {
      if (ex == null) {
        return null;
      } else if (ex.getCause() instanceof NotFoundException) {
        return configStore.doSomething(); /** returns a CompletionStage<Void> **/
      }
      throw new CompletionException(ex.getCause());
    })
.thenCompose(x -> x); /** error points here **/

我认为这是必要的,因为不会解开一个,导致在内部链接时出现。.thenCompose(x -> x);.handle(...)CompletionStage<...>CompletionStage<CompletionStage<...>>.handle(...)

为了解决这个错误,我还尝试返回这个而不是......null

.handle(
    (result, ex) -> {
      if (ex == null) {
        return CompletableFuture.completedFuture(null); /** tried this **/
      } else if ...

...但后来我收到这个错误(屏幕截图以获取更多上下文):

enter image description here

java nullpointerexception completable-future

评论


答:

1赞 Andrew Cheong 8/7/2023 #1

在写问题时想通了;自我回答,因为我的 Google 和 SO 搜索没有显示错误消息,没有将我指向此解决方案。

该解决方案实际上是由 IntelliJ 建议的(屏幕截图中的蓝色文本),但我没有看到它。由于类型不明确,因此必须像这样转换表达式:null

.handle(
    (result, ex) -> {
      if (ex == null) {
        return CompletableFuture.<Void>completedFuture(null); /** cast to <Void> **/
      } else if ...

评论

1赞 Holger 8/21/2023
这适用于,但你的原版呢?completedFuture(null)configStore.doSomething()
0赞 Andrew Cheong 8/21/2023
我相信 doSomething() 的 protobuf 的 CompletionStage<Void>(或 CompletionStage<Empty>的签名——两者都有效)给出了所需的“提示”。
1赞 Holger 8/21/2023
然后,也应该起作用。.handle( (result, ex) -> ex == null? CompletableFuture.completedFuture(null): ex.getCause() instanceof NotFoundException? configStore.doSomething(): CompletableFuture.failedFuture(ex.getCause()) ) .thenCompose(x -> x);
0赞 Andrew Cheong 8/21/2023
哦,所以使用 failedFuture() 而不是抛出 CompletionException() 会给出它需要的类型提示。failedFuture() 的语义似乎也优于我。谢谢!
1赞 Holger 8/21/2023
使用允许使用三元运算符 (),它比这里具有更好的类型推断。failedFuture()condition? value1: value2if(condition) return value1; else return value2;