为什么要使用异常
在没有异常处理的语言中,就必须使用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