美文网首页
Java Exception

Java Exception

作者: sunpy | 来源:发表于2018-08-05 22:17 被阅读21次

    介绍

    异常就是阻止当前方法或者作用域继续执行的错误。java中的异常主要分为Error异常和Exception异常。两个都继承自Throwable。
           Error异常主要是用来表示编译时和系统中的错误。
           Exception异常指一般的可以抛出的异常,这类异常需要通过程序去捕获然后进行处理。Exception异常通常是java程序员关心的。

    Java异常终止模型

    Java本身支持终止模型。程序从某一个小点发生异常,那么程序将无法回调异常发生的地方继续执行。意思就是一旦异常抛出,那么就标明错误已经无法挽回了,也不能回来继续执行了。这样就需要我们对于可能发生的异常做假设。

    public class Dog {
    
        public static void main(String[] args) {
            String str = null;
            System.out.println(str.charAt(0));
            System.out.println("123456");
        }
    }
    

    结果:


    1.jpg

    解释:可以发现程序抛出空指针异常,然后程序终止,打印123456也执行。

    Java异常捕获

    前面提到了Java的终止模型,需要我们自己对可能发生的异常进行捕获。

        public static void main(String[] args) throws Exception {
            try {
                int i  = 3 / 0;
            } catch (ArithmeticException e) {
                throw new RuntimeException(e);
            } finally {
                System.out.println("123456");
            }
        }
    
    2.jpg

    解释:此处除数为0,然后抛出算术异常。

    1. Java异常链,在我们捕获异常时,想抛出一个新的异常,希望把原始异常信息保存下来,最终向上层传递,统一处理,这条链叫异常链。现在Throwable的子类都需要传递一个Throwable对象作为参数。通过这个对象将原始异常传递给新的异常,这样就可以保证虽然当前位置创建抛出新的异常,但是通过这个新的异常也可以找回原始的异常。
    2. finally子句作用,可以保证不管异常怎样执行,finally子句一定会执行。这样就可以保证,我们在发生异常时,依然可以关闭流等操作。
      finally注意的点:
      ① return中使用finally:因为finally语句一定会执行,所以我们可以在方法中写多个返回。
    public class Dog {
    
        public static void eatFood(int foodType) {
            try {
                if (foodType == 1) {
                    return;
                }
            } finally {
                System.out.println("123456");
            }   
        }
        
        
        public static void main(String[] args) throws Exception {
            eatFood(1);
        }
    }
    

    结果:


    3.jpg

    ② break中使用finally:因为finally语句一定会执行,所以虽然在while语句中写finally语句,跳出循环,finally语句也会执行。

        public static void main(String[] args) throws Exception {
            while (true) {
                try {
                    break;
                } finally {
                    System.out.println("123456");
                }
            }
        }
    

    结果:


    4.jpg

    异常匹配顺序

    当系统抛出异常时,系统处理异常会按照程序的顺序找出最近的处理程序。找到匹配的处理程序进行处理异常之后,就不查找了。

    public static void main(String[] args) throws Exception {
            try {
                int i = 3 / 0 ;
                String str = null;
                str.charAt(0);
            } catch(NullPointerException e) {
                throw new RuntimeException(e);
            } catch(ArithmeticException e1) {
                throw new RuntimeException(e1);
            }
        }
    
    5.jpg

    解释:
    通过例子可以发现,空指针异常虽然在代码上是距离除数为0的最近处理程序。但是却不是匹配的处理程序。并且还可以看出当抛出算术异常时,程序将终止,将不会向继续查找空指针异常。

    异常丢失的BUG

    当我们在finally语句中抛出了异常,那么之前捕获的异常将会被取代,编程时需注意。

        public static void main(String[] args) throws Exception {
            try {
                int i = 3 / 0;
            } catch (ArithmeticException e) {
                throw new RuntimeException(e);
            } finally {
                String str = null;
                str.charAt(0);
            }
        }
    

    结果:


    6.jpg

    解释:可以发现finally中的空指针异常取代了之前捕获的算术异常。

    Excpetion和Error的区别

    Error:主要是系统出错,jvm处于非正常的状态,这点我们是无法控制的,譬如NoClassDefFoundErr。
    Exception:主要分为两类,一个是可以在编译器检查出的异常,譬如:IOException、InterruptedException;还有一个是不可检查的异常,譬如:空指针异常,下标越界异常,而这类异常也可以说是运行期异常RuntimeException。
    在网上找到一张图:


    异常图.jpg

    经典面试题

    NoClassDefFoundError 和 ClassNotFoundException区别
    NoClassDefFoundError抛出的原因:
    JVM在使用ClassLoader来实现类加载时,在类路径上没有找到对应的class文件。而最终的原因就是在jvm运行时期,没有加载到jar包中的类.class。
    ClassNotFoundException抛出的原因:
    spring中配置不好会经常抛出这个错误,主要是因为spring通过类名采用反射的方式Class.forName来加载类,jvm在类路径上没有找到类名对应的类,那么就会抛出这个异常。

    相关文章

      网友评论

          本文标题:Java Exception

          本文链接:https://www.haomeiwen.com/subject/zqfivftx.html