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;
    }
  • 相关阅读:
    热血投篮~手机游戏图像外包,美术完成度超过80%。现在需要对部分元素进行修改,价格
    BetaTank 1.0.1 手机 游戏 Nokia Symbian 塞班
    弹弓弹球 (banus) Android 游戏
    欢迎反馈意见
    Which Macros should I use? Themida的SDK中应该怎么使用各种宏?
    通过Daffodil for VS使VS2010的IDE可以用VC6 VC7.1 VC9等编译器进行项目编译
    STL中各种容器效率
    AcceptEx获取远程ip和端口
    PC寄存器
    VC6 sp6补丁地址
  • 原文地址:https://www.cnblogs.com/bulrush/p/13405762.html
Copyright © 2011-2022 走看看