whenComplete
的文档说:
返回与此阶段具有相同结果或异常的新完成阶段,该阶段在此阶段完成时执行给定的操作。
(强调我的)
这意味着异常不会被此阶段吞噬,因为它应该具有相同的结果或异常。但是,您可能会惊讶地发现,后续阶段将收到包装在 中的上一阶段的异常,如此处所述,因此它不是完全相同的异常: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
请注意,您始终可以在一个阶段追加多个操作,而不是链接:
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