このコードでは:
doSomethingThatMightThrowAnException()
.whenComplete((result, ex) -> doSomethingElse()})
.exceptionally(ex -> handleException(ex));
doSomethingThatMightThrowAnException
からの例外がある場合、doSomethingElse
とhandleException
の両方が実行されますか、それともwhenComplete
またはexceptionally
のどちらかが例外を消費しますか?
編集:
doSomethingThatMightThrowAnException
は、CompletableFuture
を返す可能性があるcompleteExceptionally
を返します。これは私が話している例外です。
whenComplete
の[/ documentation]には次のように書かれています:
このステージが完了すると、指定されたアクションを実行する新しいCompletionStage このステージと同じ結果または例外を持つを返します。
(強調鉱山)
これは、同じ結果または例外を持つことになっているため、このステージで例外が飲み込まれないことを意味します。ただし、 here で説明されているように、後続のステージがCompletionException
内にラップされた前のステージの例外を受け取ることに驚かれる可能性があるため、厳密には同じ例外:
CompletableFuture<String> test=new CompletableFuture<>();
test.whenComplete((result, ex) -> System.out.println("stage 2: "+result+"\t"+ex))
.exceptionally(ex -> { System.out.println("stage 3: "+ex); return ""; });
test.completeExceptionally(new IOException());
印刷されます:
stage 2: null Java.io.IOException
stage 3: Java.util.concurrent.CompletionException: Java.io.IOException
連鎖するのではなく、常に1つのステージに複数のアクションを追加できることに注意してください。
CompletableFuture<String> test=new CompletableFuture<>();
test.whenComplete((result, ex) -> System.out.println("stage 2a: "+result+"\t"+ex));
test.exceptionally(ex -> { System.out.println("stage 2b: "+ex); return ""; });
test.completeExceptionally(new IOException());
stage 2b: Java.io.IOException
stage 2a: null Java.io.IOException
もちろん、現在、ステージ間に依存関係はありません2a
および2b
、それらの間には順序がなく、非同期アクションの場合、それらは同時に実行される可能性があります。
例外的に メソッドの状態:
このCompletableFutureが完了したときに完了する新しいCompletableFutureを返します。例外の指定された関数の結果が、例外的に完了したときにこのCompletableFutureの完了をトリガーします。それ以外の場合、このCompletableFutureが正常に完了すると、返されたCompletableFutureも同じ値で正常に完了します。注:whenCompleteおよびhandleメソッドを使用すると、この機能のより柔軟なバージョンを利用できます。
これはそうではありません。私見は最も明確な英語で書かれていますが、例外がスローされた場合、exceptionally
アクションのみがトリガーされることを意味します。例外がスローされない場合、normal
アクションのみが実行されます。
doSomethingThatMightThrowAnException()
は.whenComplete((result, ex) -> doSomethingElse()})
および.exceptionally(ex -> handleException(ex));
とチェーンされますが、例外がスローされると、チェーン内にオブジェクトが渡されないため、例外はすぐに終了します。
例外は呼び出し元にスローされるので、doSomethingThatMightThrowAnException()
が内部で例外をキャッチしない限りスローされます。これがあなたのクラスである場合、それがスローするかどうかを知る必要があります。そうでない場合は、使用しているライブラリのドキュメントを確認してください。