首页 > 解决方案 > finally 块等效于 CompletableFuture 中的异常处理

问题描述

我有CompletableFuture哪个可以返回结果或异常。我想在出现异常和正常结果的情况下执行一些通用代码。类似于try catch finally

当前实施

CompletableFuture<Integer> future= CompletableFuture.supplyAsync(this::findAccountNumber)
                             .thenApply(this::calculateBalance)                      
                             .thenApply(this::notifyBalance)
                             .exceptionally(ex -> {
                                 //My Exception Handling logic 
                                 return 0;
                             });

我可以把我的最终逻辑放在哪里?

标签: java-8completable-future

解决方案


最接近的等价物finallywhenComplete。像 一样handle,它接受一个函数,接收结果值或 throwable,但它不提供替换结果值,而是新的完成阶段不会改变结果,就像finally.

所以

static int decode(String s) {
    try {
        return Integer.parseInt(s);
    }
    finally {
        System.out.println("finally action");
    }
}

相当于

static int decode1(String s) {
    return CompletableFuture.completedFuture(s)
        .thenApply(Integer::parseInt)
        .whenComplete((i,t) -> System.out.println("finally action"))
        .join();
}

所以当使用 with

for(String s: Arrays.asList("1234", "foo bar")) try {
    System.out.println("decoded: "+decode(s));
} catch(Exception ex) {
    System.out.println("decoding "+s+" failed with "+ex);
}

第一个变体打印

finally action
decoded: 1234
finally action
decoding foo bar failed with java.lang.NumberFormatException: For input string: "foo bar"

和后者打印

finally action
decoded: 1234
finally action
decoding foo bar failed with java.util.concurrent.CompletionException: java.lang.NumberFormatException: For input string: "foo bar"

两者的共同点是,如果 try 块/前一个阶段异常完成,则 finally 操作中引发的异常将取代原始结果,从而隐藏异常。


推荐阅读