gpt4 book ai didi

java - CompletionStage 是否总是将异常包装在 CompletionException 中?

转载 作者:搜寻专家 更新时间:2023-10-30 19:45:45 25 4
gpt4 key购买 nike

CompletionStage Javadoc 指出:

[...] if a stage's computation terminates abruptly with an (unchecked) exception or error, then all dependent stages requiring its completion complete exceptionally as well, with a CompletionException holding the exception as its cause.

看到异常完成总是在 CompletionException 中包装异常,为什么 exceptionally()whenComplete()handle() 将异常表示为 Throwable 而不是 CompletionException?

这很重要,因为它可以防止在这些方法中直接重新抛出异常。

这些方法是否可能接收到 CompletionException 以外的异常?或者我可以安全地强制转换为这种类型吗?

(我在本地运行了一些测试,并深入研究了 CompletableFuture 源代码,乍一看,我没有看到如何抛出任何其他类型的异常。)

最佳答案

Is it possible for these methods to receive an exception other than CompletionException?

是的,这是可能的,您不应该在没有instanceof 检查(或检查您的使用情况)的情况下强制转换为CompletionException

举个例子

CompletableFuture<Void> root = new CompletableFuture<>();
root.whenComplete((v, t) -> {
System.out.println(t.getClass()); // class java.io.IOException
});
root.completeExceptionally(new IOException("blow it up"));

whenComplete 将收到 IOException 而不是包装它的 CompletionException。相同的行为适用于 exceptionallyhandle


阶段的计算在 Javadoc 中定义:

The computation performed by a stage may be expressed as a Function, Consumer, or Runnable (using methods with names including apply, accept, or run, respectively) depending on whether it requires arguments and/or produces results.

我相信这句话

if a stage's computation terminates abruptly with an (unchecked) exception or error

指的是那些 Function#applyConsumer#acceptRunnable#run 方法之一,因为 thrown exception 突然终止,不是因为某个阶段通过其他机制异常完成。

另请注意,Javadoc 说

This interface does not define methods for initially creating, forcibly completing normally or exceptionally, probing completion status or results, or awaiting completion of a stage. Implementations of CompletionStage may provide means of achieving such effects, as appropriate

换句话说,该接口(interface)允许实现异常地完成阶段,而不会突然终止任何计算。我认为这允许新的行为。


如果我们扩展之前的例子

CompletableFuture<Void> root = new CompletableFuture<>();
CompletableFuture<Void> child = root.whenComplete((v, t) -> {
System.out.println(t.getClass()); // class java.io.Exception
});
child.whenComplete((v, t) -> {
System.out.println(t.getClass()); // class java.util.concurrent.CompletionException
});
root.completeExceptionally(new IOException("blow it up"));

您会注意到附加到 child 的完成收到一个 CompletionException 包装原始 IOException。从 Javadoc 来看,这对我来说并不明显,它指出

Returns a new CompletionStage with the same result or exception as this stage

总而言之,似乎来自 completeExceptionally 的原始异常被传递给直接依赖项,而依赖项的依赖项接收封闭的 CompletionException

关于java - CompletionStage 是否总是将异常包装在 CompletionException 中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49230980/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com