CompletionStage是否始终在CompletionException中包装异常? [英] Does CompletionStage always wrap exceptions in CompletionException?
问题描述
CompletionStage Javadoc声明:
The CompletionStage Javadoc states:
[...]如果一个阶段的计算突然以(未经检查的)异常或错误终止,那么所有需要完成的依赖阶段异常完成,使用CompletionException将异常作为其原因。
[...] 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.
看作异常完成总是在<$ c $中包装异常c> CompletionException 为什么 exceptionally()
, whenComplete()
和 handle()
将异常表示为 Throwable
而不是 CompletionException
?
Seeing as exceptional completions always wrap exceptions in CompletionException
why do exceptionally()
, whenComplete()
and handle()
represent the exception as Throwable
instead of CompletionException
?
这很重要,因为它可以防止人们直接在这些方法中重新抛出异常。
This matters because it prevents one from directly re-throwing exceptions inside these methods.
是否可以这些方法接收 CompletionException
?以外的异常或者我可以安全地强制转换为这种类型吗?
Is it possible for these methods to receive an exception other than CompletionException
? Or can I safely force a cast to this type?
(我在本地运行了一些测试,以及挖掘CompletableFuture源代码,乍一看,我做的没有看到如何抛出任何其他类型的异常。)
(I ran some tests locally, as well as dig through the CompletableFuture source-code and, at first glance, I do not see how any other type of exception could be thrown.)
推荐答案
这些是否可能接收
以外的例外的方法CompletionException
?
是,有可能并且您不应该在没有 instanceof
检查(或查看您的使用情况)的情况下转换为 CompletionException
。
Yes, it is possible and you shouldn't cast to CompletionException
without an instanceof
check (or a review of your usage).
以此为例
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
包装它。相同的行为适用于异常
和句柄
。
whenComplete
will receive the IOException
rather than a CompletionException
wrapping it. The same behavior applies to exceptionally
and handle
.
阶段的计算在Javadoc中定义:
A stage's computation is defined in the Javadoc:
阶段执行的计算可能是表示为
函数
,
消费者
或Runnable
(使用名称包括apply,
accept或run的方法),具体取决于它是否需要
参数和/或产生结果。
The computation performed by a stage may be expressed as a
Function
,Consumer
, orRunnable
(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
指的是函数#apply
中的一个, Consumer #accept
或 Runnable#run
因抛出异常 ,不是因为一个阶段通过其他机制异常完成。
is referring to one of those Function#apply
, Consumer#accept
, or Runnable#run
methods terminating abruptly because of a thrown exception, not because a stage completed exceptionally through some other mechanism.
另请注意,Javadoc说
Note also that the Javadoc says
此接口未定义方法最初创建,
强行正常完成或异常,探测完成
状态或结果,或等待完成阶段。实现
的CompletionStage
可以提供实现此类效果的方法,因为
合适
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
换句话说,该接口允许实现异常完成阶段而不会突然终止任何计算。我认为这允许新的行为。
In other words, the interface allows implementations to complete stages exceptionally without abruptly terminating any computation. I think this allows for new behavior.
如果我们从之前扩展我的例子
If we extend my example from before
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"));
您会注意到孩子所附的完成
收到 CompletionException
包装原始 IOException
。对于我来说,这对 Javadoc ,表示
You'll notice the completion attached to the child
receives a CompletionException
wrapping the original IOException
. This isn't obvious to me from the Javadoc, which states
返回一个新的
CompletionStage
相同结果或异常为
此阶段
Returns a new
CompletionStage
with the same result or exception as this stage
总而言之,似乎将来自 completeExceptionally
的原始异常传递给直接家属,而受抚养人的家属则收到一个封闭的 CompletionException
。
All in all, it seems like the raw exception from a completeExceptionally
is passed down to direct dependents, while dependents of dependents receive an enclosing CompletionException
.
这篇关于CompletionStage是否始终在CompletionException中包装异常?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!