Java异常处理

来源:互联网 发布:深入浅出node.js 微盘 编辑:程序博客网 时间:2024/06/09 13:49

这里写图片描述
先放图。
java所有异常类,继承自java.lang.Throwable。Throwable有两个直接子类,Error类和Exception类。

  1. Error(错误):一般指虚拟机相关的问题,入系统崩溃、虚拟机出错、动态链接失败等。这种错误无法恢复,也不可捕获,会导致程序运行中断。例如内存溢出错误。
  2. Exception(异常):一般分为Checked(受检)异常和Runtime异常,所有RuntimeException类及其子类的实例被称为Runtime异常,不属于该范畴的异常则被称为CheckedException。
    对Checked异常处理方法有两种:
    • 当前方法知道如何处理该异常,则用try…catch块来处理该异常。
    • 当前方法不知道如何处理,则在定义该方法是声明抛出该异常。

Error

当我们启动程序,结果启动失败,报错。这种情况下,大部分都是Error导致的。例如java.lang.NoClassDefFoundError等。出现这种错误,需要我们去排查自己的代码。

Exception

如上所述,异常分为受检异常和运行时异常。下面针对这两种异常,分别讨论。

CheckedException

除了RuntimeException,其他均为CheckedException。如上所述,该类异常,强制我们通过try、catch捕获或通过throws声明抛出。
这里写图片描述
如上图,如果我们不对受检异常进行处理,编译会报错。有两种方式处理异常:

  1. 通过try、catch语句捕获
    public static void main(String[] args){        getFile();        System.out.println("运行正常结束");    }    public static void getFile(){        File file = new File("Test");        InputStream in = null;        try {            in = new FileInputStream(file);        } catch (FileNotFoundException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }        System.out.println("异常后语句");    }

如上,当出现FileNotFoundException异常时,会打印出错误堆栈信息。同时,程序会继续往下运行

java.io.FileNotFoundException: Test (系统找不到指定的文件。)    at java.io.FileInputStream.open(Native Method)    at java.io.FileInputStream.<init>(Unknown Source)    at com.error.TestThrow.getFile(TestThrow.java:21)    at com.error.TestThrow.main(TestThrow.java:11)异常后语句运行正常结束
  1. 通过throws抛出
    我们可以在方法声明上添加throws,声明该方法可能会抛出异常,并将其交由上层,也就是调用它的方法处理。而上层也有两种选择,一种是继续往上抛,一种是通过try、catch捕获。先看直接抛出的:
    public static void main(String[] args) throws FileNotFoundException{        getFile();        System.out.println("运行正常结束");    }    public static void getFile() throws FileNotFoundException{        File file = new File("Test");        InputStream in = null;        in = new FileInputStream(file);        System.out.println("异常后语句");    }

运行结果如下:

Exception in thread "main" java.io.FileNotFoundException: Test (系统找不到指定的文件。)    at java.io.FileInputStream.open(Native Method)    at java.io.FileInputStream.<init>(Unknown Source)    at com.error.TestThrow.getFile(TestThrow.java:20)    at com.error.TestThrow.main(TestThrow.java:11)

从结果可以看出,由于异常交由上层处理,出现异常后的代码不再执行。
再看,如果上层通过try、catch捕获运行结果如何:

    public static void main(String[] args){        try {            getFile();        } catch (FileNotFoundException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }        System.out.println("运行正常结束");    }

结果如下:

java.io.FileNotFoundException: Test (系统找不到指定的文件。)    at java.io.FileInputStream.open(Native Method)    at java.io.FileInputStream.<init>(Unknown Source)    at com.error.TestThrow.getFile(TestThrow.java:25)    at com.error.TestThrow.main(TestThrow.java:12)运行正常结束

通过上面,我们可以得出如下结论:
对于受检异常,如果通过try、catch捕获,后续代码会继续执行;如果通过throws声明抛出异常,则后续代码不再执行。如果最上层也未捕获,则交由虚拟机处理,此时会导致程序终止。

RuntimeException

该类异常,不要求任何处理。如下例:

    public static void div(){        int a=3;        int b=0;        int c = a/b;        System.out.println("异常后语句");    }

运行结果如下:

Exception in thread "main" java.lang.ArithmeticException: / by zero    at com.error.TestThrow.div(TestThrow.java:30)    at com.error.TestThrow.main(TestThrow.java:11)

导致程序中止。

关于throws和throw

上面提到了throws,它和throw是什么关系呢?
throw可以主动抛出特定异常,如下例:

public static void div() {        int a=3;        int b=0;        if(0==b){            throw new ArithmeticException();        }else{            int c = a/b;        }        System.out.println("异常后语句");    }

程序主动抛出ArithmeticException,结果如下:

Exception in thread "main" java.lang.ArithmeticException    at com.error.TestThrow.div(TestThrow.java:30)    at com.error.TestThrow.main(TestThrow.java:11)

那么throw还有什么用呢?实际应用中,可能碰到这种情况,单靠一个类,无法完成异常处理,但通过try、catch后,上层又无法再次捕获,此时可以在catch中通过throw主动抛出异常,交由上层处理。

总结

通过上述例子可以看出,不论是Error还是Exception,都会导致程序终止。但对于Exception,通过try、catch捕获处理后,不会导致程序终止,后续代码仍可继续执行。