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;
    }
  • 相关阅读:
    Max Sum Plus Plus HDU
    Monkey and Banana HDU
    Ignatius and the Princess IV HDU
    Extended Traffic LightOJ
    Tram POJ
    Common Subsequence HDU
    最大连续子序列 HDU
    Max Sum HDU
    畅通工程再续
    River Hopscotch POJ
  • 原文地址:https://www.cnblogs.com/bulrush/p/13405762.html
Copyright © 2011-2022 走看看