zoukankan      html  css  js  c++  java
  • 异常

    一:Unchecked Exception

    Unchecked exception也叫做RuntimeException,出现RuntimeException通常是因为我们的代码有问题。RuntimeException是不需要被捕获的。也就是说如果有RuntimeException,没有捕获也可以通过编译。

    但是后续的代码就不会再进行处理了。

    List<Integer> integers = Arrays.asList(0,1,2,3,4,5);
            integers.forEach(i->{
                System.out.println(1 / i);
            });

    输出:

    Exception in thread "main" java.lang.ArithmeticException: / by zero
        at test.testJava.Test2.lambda$main$0(Test2.java:13)
        at java.util.Arrays$ArrayList.forEach(Arrays.java:3880)
        at test.testJava.Test2.main(Test2.java:12)

    用try-catch捕获后程序可以继续进行。

    List<Integer> collect = Stream.of(1, 0, 3, 4, 0, 5, 6).collect(Collectors.toList());
            collect.forEach(i -> {
                try {
                    System.out.println(1 / i);
                } catch (ArithmeticException e) {
                    log.info("不能为0:{}",i);
                    e.printStackTrace();
                }
            });

    输出:

    1
    18:31:57.614 [main] ERROR test.testJava.Test2 - 不能为0:0
    0
    0
    18:31:57.627 [main] ERROR test.testJava.Test2 - 不能为0:0
    0
    0
    java.lang.ArithmeticException: / by zero
        at test.testJava.Test2.lambda$main$0(Test2.java:21)
        at java.util.ArrayList.forEach(ArrayList.java:1257)
        at test.testJava.Test2.main(Test2.java:19)
    java.lang.ArithmeticException: / by zero
        at test.testJava.Test2.lambda$main$0(Test2.java:21)
        at java.util.ArrayList.forEach(ArrayList.java:1257)
        at test.testJava.Test2.main(Test2.java:19)

    简单但是破坏了lambda表达式的最佳实践。代码变得臃肿。

    将try,catch移到一个wrapper方法中:

    static Consumer<Integer> lambdaWrapper(Consumer<Integer> consumer) {
            return i -> {
                try {
                    consumer.accept(i);
                } catch (ArithmeticException e) {
                    log.error("Arithmetic Exception occured : " + e.getMessage());
                    System.err.println(
                            "Arithmetic Exception occured : " + e.getMessage());
                }
            };
        }

    使用:

    List<Integer> collect = Stream.of(1, 0, 3, 4, 0, 5, 6).collect(Collectors.toList());
    collect.forEach(
    lambdaWrapper(i -> {
    System.out.println(1 / i);
    })
    );

    输出:

    1
    18:40:44.594 [main] ERROR test.testJava.Test2 - Arithmetic Exception occured : / by zero
    0
    0
    18:40:44.600 [main] ERROR test.testJava.Test2 - Arithmetic Exception occured : / by zero
    0
    0
    Arithmetic Exception occured : / by zero
    Arithmetic Exception occured : / by zero

    但是上面的wrapper固定了捕获ArithmeticException,我们再将其改编成一个更通用的类:

    static <T, E extends Exception> Consumer<T>
        consumerWrapperWithExceptionClass(Consumer<T> consumer, Class<E> clazz) {
    
            return i -> {
                try {
                    consumer.accept(i);
                } catch (Exception ex) {
                    try {
                        E exCast = clazz.cast(ex);
                        log.error("Exception occured:{},Exception的名字:{}" ,exCast.getMessage(),exCast.getClass());
                        System.err.println(
                                "Exception occured : " + exCast.getMessage());
                    } catch (ClassCastException ccEx) {
                        throw ex;
                    }
                }
            };
        }

    使用:

    List<Integer> collect = Stream.of(1, 0, 3, 4, 0, 5, 6).collect(Collectors.toList());
            collect.forEach(
                    consumerWrapperWithExceptionClass(i ->{
                                System.out.println(1 / i);
                            }
                        ,ArithmeticException.class
                )
            );

    输出:

    1
    18:49:52.890 [main] ERROR test.testJava.Test2 - Exception occured:/ by zero,Exception的名字:class java.lang.ArithmeticException
    0
    0
    18:49:52.917 [main] ERROR test.testJava.Test2 - Exception occured:/ by zero,Exception的名字:class java.lang.ArithmeticException
    0
    0
    Exception occured : / by zero
    Exception occured : / by zero

     二:checked Exception

    checked Exception是必须要处理的异常,我们还是看个例子:

    static void throwIOException(Integer integer) throws IOException {
        }
    List<Integer> integers = Arrays.asList(1, 2, 3, 4, 5);
            integers.forEach(i -> throwIOException(i));

    上面我们定义了一个方法抛出IOException,这是一个checked Exception,需要被处理,所以在下面的forEach中,程序会编译失败,因为没有处理相应的异常。

    static <T> Consumer<T> consumerWrapper(
                ThrowingConsumer<T, Exception> throwingConsumer) {
    
            return i -> {
                try {
                    throwingConsumer.accept(i);
                } catch (Exception ex) {
                    throw new RuntimeException(ex);
                }
            };
        }

    调用:

    integers.forEach(consumerWrapper(i -> throwIOException(i)));

    封装异常,用来通用

    static <T, E extends Exception> Consumer<T> consumerWrapperWithExceptionClass(
                ThrowingConsumer<T, E> throwingConsumer, Class<E> exceptionClass) {
    
            return i -> {
                try {
                    throwingConsumer.accept(i);
                } catch (Exception ex) {
                    try {
                        E exCast = exceptionClass.cast(ex);
                        System.err.println(
                                "Exception occured : " + exCast.getMessage());
                    } catch (ClassCastException ccEx) {
                        throw new RuntimeException(ex);
                    }
                }
            };
        }

    调用:

    integers.forEach(consumerWrapperWithExceptionClass(
                    i -> throwIOException(i), IOException.class));
    package test.testJava;
    
    /**
     * @FunctionalInterface   函数式接口
     *      1:接口有且仅有一个抽象方法
     *      2:允许定义静态方法
     *      3:允许定义默认方法
     *      4:允许java.lang.Object中的public方法
     *      该注解不是必须的,如果一个接口符合"函数式接口"定义,那么加不加该注解都没有影响。
     *      加上该注解能够更好地让编译器进行检查。如果编写的不是函数式接口,但是加上了@FunctionInterface,那么编译器会报错
     *
     * @param <T>
     * @param <E>
     */
    @FunctionalInterface
    public interface ThrowingConsumer<T, E extends Exception> {
        void accept(T t) throws E;
    }
  • 相关阅读:
    TP5学习笔记- 使用命令行创建控制器
    centos 7 下安装mysql5.7
    webserver的安装
    linux常用命令 服务器硬件资源信息
    SSH 安装/ config 配置以及免密码登录
    thinkphp ,laravel,yii2运行环境搭建.
    分享几个博客园代码样式的CSS配置(复制黏贴即可)
    vue中通过.sync修饰符实现子组件修改父组件数据
    vue中$attrs和$listeners以及inheritAttrs的用法
    Vue项目中实现用户登录及token验证
  • 原文地址:https://www.cnblogs.com/bulrush/p/13405762.html
Copyright © 2011-2022 走看看