问题描述
Javadoc声明:
The CompletionStage Javadoc states:
看作异常完成总是在<$ 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.)
推荐答案
是,有可能并且您不应该在没有 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:
我相信这句话
指的是函数#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
换句话说,该接口允许实现异常完成阶段而不会突然终止任何计算。我认为这允许新的行为。
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
。对于我来说,这对,表示
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
总而言之,似乎将来自 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中包装异常?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!