• 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:	"+divide(6,3).get());
                System.out.println("exception:	"+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:	"+ex.getMessage());
                        }
                    });
        }
    
            try {
                System.out.println("success:	"+whenComplete(6,3).get());
                System.out.println("exception:	"+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:	"+ex.getMessage());
                        return 0;
                    });
        }
    
            try {
    System.out.println("success:	"+FutureTest.exceptionally(6,3).get());
                System.out.println("exception:	"+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()方法,它可以从异常中恢复过来。



     
  • 相关阅读:
    安装提示设备为允许启用的解决办法
    xargs命令
    MariaDB链接超时优化
    灵活QinQ配置
    批量删除.pyo后缀的文件
    netcat的使用
    xxe(xml外部实体注入)
    渗透测试前:信息收集
    windows文件命名特性利用漏洞
    ssrf(Server-Side Request Forgery)
  • 原文地址:https://www.cnblogs.com/song27/p/15146248.html
Copyright © 2020-2023  润新知