function性Java – whenComplete和exception之间的交互

在这段代码中:

doSomethingThatMightThrowAnException() .whenComplete((result, ex) -> doSomethingElse()}) .exceptionally(ex -> handleException(ex)); 

doSomethingThatMightThrowAnException存在exception时, doSomethingElsehandleException运行,或者是whenComplete还是exception消耗的exceptionally

编辑:

doSomethingThatMightThrowAnException返回一个CompletableFuture ,它可能会CompletableFuture completeExceptionally 。 这是我所说的例外。

whenComplete的文档说:

返回与此阶段具有相同结果或exception的新CompletionStage ,该阶段在此阶段完成时执行给定操作。

(强调我的)

这意味着此阶段不会吞下exception,因为它应该具有相同的结果或exception。 但是,您可能会对后续阶段将收到CompletionException中包含的前一阶段的exception这一事实感到惊讶,如此处所述,因此它不是完全相同的exception:

 CompletableFuture 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 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 

当然,由于现在阶段2a2b之间没有依赖关系,因此它们之间没有排序,并且在异步操作的情况下,它们可以同时运行。

特殊方法指出:

返回一个新的CompletableFuture,该CompletableFuture在此CompletableFuture完成时完成,exception的给定函数的结果在exception完成时触发此CompletableFuture的完成; 否则,如果此CompletableFuture正常完成,则返回的CompletableFuture也会以相同的值正常完成。 注意:使用完成和处理方法时,可以使用此function的更灵活版本。

这不是,恕我直言用最清晰的英文写的,但我想说这意味着如果抛出exception,只会触发exceptionally动作。 如果没有抛出exception,则仅执行normal操作。

doSomethingThatMightThrowAnException()与.whenComplete((result,ex) – > doSomethingElse()})和.exceptionally(ex – > handleException(ex)); 但如果它抛出一个exception就会在那里结束,因为链中不会传递任何对象。

请记住,exception将抛出调用者,因此除非doSomethingThatMightThrowAnException()在内部捕获exception,否则它将抛弃。 如果这是你的class级,你应该知道它是否投掷,如果没有检查你使用的lilbraris的文档。