gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-01 22:22:06 24 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。同样的行为也适用于异常(exception)handle

<小时/>

阶段的计算在 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

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

另请注意,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 的完成会收到一个包含原始 IOExceptionCompletionException。从 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/58582832/

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