CompletionStage Javadocは次のように述べています。
[...]ステージの計算が(チェックされていない)例外またはエラーで突然終了した場合、完了を必要とするすべての依存ステージも例外的に完了し、CompletionExceptionが例外を原因として保持します。
例外補完は常にCompletionException
で例外をラップするものと見なされる理由exceptionally()
、whenComplete()
、handle()
は例外をThrowable
として表す/ CompletionException
?
これは、これらのメソッド内で例外を直接再スローするのを防ぐため、重要です。
これらのメソッドがCompletionException
以外の例外を受け取ることは可能ですか?または、このタイプにキャストを安全に強制できますか?
(私はいくつかのテストをローカルで実行しただけでなく、CompletableFutureソースコードを使ってDigしましたが、一見したところ、他の種類の例外がスローされる方法がわかりません。)
これらのメソッドが
CompletionException
以外の例外を受け取ることはありますか?
はい、可能です。CompletionException
チェック(または使用方法のレビュー)なしでinstanceof
にキャストしないでください。
この例を取る
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
を受け取ります。同じ動作がexceptionally
とhandle
にも当てはまります。
ステージの計算は、Javadocで定義されています。
ステージによって実行される計算は、
Function
、Consumer
、またはRunnable
として表すことができます(それぞれ、apply、accept、runなどの名前のメソッドを使用)。引数を必要とするか、結果を生成します。
私はこの見積もりを信じています
ステージの計算が(チェックされていない)例外またはエラーで突然終了した場合
それらの1つを参照していますFunction#apply
、Consumer#accept
、またはRunnable#run
メソッドは スローされた例外 のために突然終了します。ステージが他のメカニズムによって例外的に完了したためではありません。
Javadocによると、
このインターフェイスは、最初に作成する、通常または例外的にを強制的に完了する、完了ステータスまたは結果を調査する、またはステージの完了を待機するためのメソッドを定義しません。
CompletionStage
の実装は、必要に応じて、このような効果を達成する手段を提供する場合があります
言い換えると、このインターフェースにより、実装は、計算を突然終了することなく、例外的にステージを完了することができます。これにより、新しい行動が可能になると思います。
前から私の例を拡張すると
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 からは明らかではありません。
このステージと同じsame結果またはexceptionを持つ新しい
CompletionStage
を返します
全体として、completeExceptionally
からの直接の例外は直接の依存関係に渡されるようですが、依存関係の依存関係は囲みCompletionException
を受け取ります。