CompletableFuture 捕獲異常方式:handle、whenComplete、exceptionally


使用 CompletableFuture 編寫代碼時,異常處理很重要。
CompletableFuture 提供了三種方法來處理它們:handle()、whenComplete() 和 exceptionly()。

 
  handle() whenComplete() exceptionly()
訪問成功 Yes Yes No
訪問失敗 Yes Yes Yes
能從失敗中恢復 Yes No Yes
能轉換結果從T 到 U Yes No No
成功時觸發 Yes Yes No
失敗時觸發 Yes Yes Yes
有異步版本 Yes Yes Yes(12版本)

 

 

 

 

 

 

 

 

 

 

1、handle()

public <U> CompletableFuture<U> handle(java.util.function.BiFunction<? super T, Throwable, ? extends U> fn)

返回一個新的 CompletionStage階段,當此階段正常或異常完成時,將使用此階段的結果和異常作為所提供函數的參數來執行。

當此階段完成時,以該階段的結果(如果沒有則為null)和該階段的異常(如果沒有則為null)作為參數調用給定函數,並且函數的結果用於完成返回的階段

不會把異常外拋出來。

    public static CompletableFuture divide(int a, int b){
        return CompletableFuture.supplyAsync(() -> a/b)
                .handle((result, ex) -> {
                    if (null != ex) {
                        System.out.println(ex.getMessage());
                        return 0;
                    } else {
                        return result;
                    }
                });
    }

        try {
            System.out.println("success:\t"+divide(6,3).get());
            System.out.println("exception:\t"+divide(6,0).get());
        } catch (Exception exception){
            System.out.println("catch="+exception.getMessage());
        }

輸出結果:
success:    2
java.lang.ArithmeticException: / by zero
exception:    0
 

2、whenComplete()

 

public CompletableFuture<T> whenComplete(java.util.function.BiConsumer<? super T, ? super Throwable> action)

 

可以訪問當前completable future的結果和異常作為參數:使用它們並執行您想要的操作。

此方法並不能轉換完成的結果。會內部拋出異常。

    public static CompletableFuture whenComplete(int a, int b){
        return CompletableFuture.supplyAsync(() -> a/b)
                .whenComplete((result, ex) -> {
                    if (null != ex) {
                        System.out.println("whenComplete error:\t"+ex.getMessage());
                    }
                });
    }

        try {
            System.out.println("success:\t"+whenComplete(6,3).get());
            System.out.println("exception:\t"+whenComplete(6,0).get());
        } catch (Exception exception){
            System.out.println("catch===="+exception.getMessage());
        }

輸出:

success:    2
whenComplete error:    java.lang.ArithmeticException: / by zero
catch====java.lang.ArithmeticException: / by zero

 

 

3、exceptionly()

 
        
public CompletableFuture<T> exceptionally(java.util.function.Function<Throwable, ? extends T> fn)

該方法僅處理異常情況:發生異常時。
如果可完成的未來成功完成,那么“異常”內部的邏輯將被跳過。

不會把內部異常拋出來。

 
        
    public static CompletableFuture exceptionally(int a, int b){
        return CompletableFuture.supplyAsync(() -> a/b)
                .exceptionally(ex -> {
                    System.out.println("ex:\t"+ex.getMessage());
                    return 0;
                });
    }

        try {
System.out.println("success:\t"+FutureTest.exceptionally(6,3).get());
            System.out.println("exception:\t"+FutureTest.exceptionally(6,0).get());
        } catch (Exception exception){
            System.out.println("catch===="+exception.getMessage());
        }


輸出:
success:    2
ex:    java.lang.ArithmeticException: / by zero
exception:    0
 
        


如果只專注於異常處理,選擇exceptionally(),它可以簡化了輸入參數,並且可以避免異常空檢查的if語句。

如果希望不影響主流程,也不加try進行捕獲,使用handle()方法,它可以從異常中恢復過來。



 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM