Java异常

为什么要使用异常

在没有异常处理的语言中,就必须使用if或switch等语句,配合所想得到的错误状况来捕捉程序里所有可能发生的错误。但为了捕捉这些错误,编写出来的代码经常有很多的if语句,有

时候这样也未必能捕捉到所有的错误,而且这样做势必导致程序运行效率的降低。Java的异常处理机制恰好改进了这一点,它易于使用并且可自行定义异常类,但是不得不说,异常也

是一个较为耗费性能的操作,因此我们需要合理地利用Java的异常处理机制,以增进程序的稳定性和效率。

异常的继承架构

异常可分为两大类:java.lang.Exception与java.lang.Error,这两个类均继承自java.lang.Throwable,上图为Throwable类的继承关系图。

习惯上将Error与Exception统称为异常类,但这两者本质上还是有不同的:

1、Error专门用来处理严重影响程序运行的错误,可是通常程序设计者不会涉及程序代码去捕捉这种错误,其原因在于即使捕捉到它,也无法给予适当的处理,比如Java虚拟机出错就属于一种Error

2、Exception包含了一般性的异常,这些异常通常在捕捉到之后便可以做妥善的处理,以确保程序继续运行

从继承架构图中可以看出,Exception扩展出数个子类,其中IOException、RuntimeException是较常用的两种。RuntimeException即使不编写异常处理的程序代码,依然可以编译成功,而这种异常必须是在程序运行时才有可能发生,比如数组索引值超出了范围。与RuntimeException不同的是,IOException一定要编写异常处理的程序代码才行,它通常用来处理输入/输出相关的操作,如对文件的访问、网络的连接等。

当异常发生时,发生异常的语句代码会抛出一个异常类的实例化对象,之后此对象与catch语句中的类的类型进行匹配,然后在相应的catch中进行处理。

try、catch、finally、throw、throws

(4)throw表示抛出一个类的实例,注意实例二字,实例意味着throw出去的是一个实例化的异常对象。所以代码的11行也可以写为"throw new NullPointerException()",至于为什么不这么写,因为写"throw new NullPointerException()"并没有返回结果中第4行、第5行中的异常堆栈。注意,throw关键字可以写在任何地方,并不强制必须写在catch块中,运行到throw所在的行,打印异常并立即退出当前方法

补充:

运行到throw所在的行,打印异常并立即退出当前方法,退出时还是会执行finally里面的语句

public class Test {
    public static void main(String[] args) throws FileNotFoundException {
        try {
            InputStream inputStream = getInputStream();
        } catch (FileNotFoundException e) {
            System.out.println("catch......");
            throw e;
            /*e.printStackTrace();*/
        }finally {
            System.out.println("finally........");
        }
        System.out.println("last.......");
    }

    public static InputStream getInputStream() throws FileNotFoundException {
        InputStream in = new FileInputStream("D:" + File.separator + "....测.xlsx");
        return in;
    }
}

结果:执行了finally里面的语句但是last未打印,直接退出了方法。

Exception in thread "main" java.io.FileNotFoundException: D:....测.xlsx (系统找不到指定的文件。)
    at java.io.FileInputStream.open0(Native Method)
    at java.io.FileInputStream.open(FileInputStream.java:195)
    at java.io.FileInputStream.<init>(FileInputStream.java:138)
    at java.io.FileInputStream.<init>(FileInputStream.java:93)
    at com.dajia.test.Test.getInputStream(Test.java:28)
    at com.dajia.test.Test.main(Test.java:16)
catch......
finally........

当不使用throw e的时候,执行了finally里面的语句且打印了last

public class Test {
    public static void main(String[] args) throws FileNotFoundException {
        try {
            InputStream inputStream = getInputStream();
        } catch (FileNotFoundException e) {
            System.out.println("catch......");
            /*throw e;*/
            e.printStackTrace();
        }finally {
            System.out.println("finally........");
        }
        System.out.println("last.......");
    }

    public static InputStream getInputStream() throws FileNotFoundException {
        InputStream in = new FileInputStream("D:" + File.separator + "....测.xlsx");
        return in;
    }
}

结果:

catch......
finally........
last.......
java.io.FileNotFoundException: D:....测.xlsx (系统找不到指定的文件。)
    at java.io.FileInputStream.open0(Native Method)
    at java.io.FileInputStream.open(FileInputStream.java:195)
    at java.io.FileInputStream.<init>(FileInputStream.java:138)
    at java.io.FileInputStream.<init>(FileInputStream.java:93)
    at com.dajia.test.Test.getInputStream(Test.java:29)
    at com.dajia.test.Test.main(Test.java:16)

参考资料:

https://www.cnblogs.com/xrq730/p/4880954.html

原文地址:https://www.cnblogs.com/zfyang2429/p/10334305.html