异常
分类
•概念
JDK 中定义了很多异常类,这些类对应了各种各样可能出现的异常事件,所有异常对象都是派生于Throwable类的一个实例。
如果内置的异常类不能够满足需要,还可以创建自己的异常类。
Java对异常进行了分类,不同类型的异常分别用不同的Java类表示,所有异常的根类为java.lang.Throwable。
Throwable下面又派生了两个子类:Error和Exception。Java异常类的层次结构如图6-2所示。
•图示
Exception
•概念
1.Exception是程序本身能够处理的异常,如:
- 空指针异常(NullPointerException)
- 数组下标越界异常(ArrayIndexOutOfBoundsException)
- 类型转换异常(ClassCastException)
- 算术异常(ArithmeticException)
- ......
2.Exception类是所有异常类的父类,其子类对应了各种各样可能出现的异常事件,通常Java的异常可分为:
- RuntimeException 运行时异常
- CheckedException 已检查异常
异常处理——捕获异常
•概念
捕获异常是通过3个关键词来实现的:try-catch-finally。
用try来执行一段程序,如果出现异常,系统抛出一个异常,可以通过它的类型来捕捉(catch)并处理它,
最后一步是通过finally语句为异常处理提供一个统一的出口,
finally所指定的代码都要被执行。
PS : catch语句可有多条,finally语句最多只能有一条。
•图示
•try
try语句指定了一段代码,该段代码就是异常捕获并处理的范围。
在执行过程中,当任意一条语句产生异常时,就会跳过该条语句中后面的代码。
代码中可能会产生并抛出一种或几种类型的异常对象,它后面的catch语句要分别对这些异常做相应的处理。
一个try语句必须带有至少一个 catch 语句块或一个 finally 语句块。
PS : 当异常处理的代码执行结束以后,不会回到 try 语句去执行尚未执行的代码。
•catch常用方法
- toString ()方法 : 显示异常的类名和产生异常的原因
- getMessage()方法 : 只显示产生异常的原因,但不显示类名
- printStackTrace()方法 : 用来跟踪异常事件发生时堆栈的内容。
PS : 这些方法均继承自Throwable类。
•catch捕获异常时的捕获顺序
如果异常类之间有继承关系,在顺序安排上需注意。
越是顶层的类,越放在下面,再不然就直接把多余的catch省略掉。
也就是先捕获子类异常再捕获父类异常。
•finally
有些语句,不管是否发生了异常,都必须要执行,那么就可以把这样的语句放到finally语句块中。
通常在 finally 中关闭程序块已打开的资源,比如:关闭文件流、释放数据库连接等。
•try-catch-finally语句块的执行过程
- 程序首先执行可能发生异常的 try 语句块。
- 如果try语句没有出现异常则执行完后跳至 finally 语句块执行。
- 如果try语句出现异常,则中断执行并根据发生的异常类型跳至相应的 catch 语句块执行处理。
- catch语句块可以有多个,分别捕获不同类型的异常。
- catch语句块执行完后程序会继续执行finally语句块。
- finally语句是可选的,如果有的话,则不管是否发生异常,finally语句都会被执行。
•Code
View Code1 import java.io.FileNotFoundException; 2 import java.io.FileReader; 3 import java.io.IOException; 4 5 public class TestTryCatch { 6 7 public static void main(String[] args) { 8 9 FileReader reader = null; 10 /* 11 * FileNotFoundException 是 IOException 的子类 12 * 所以 FileNotFoundException 在 IOException 的前面 13 */ 14 try { 15 reader = new FileReader("a.txt"); 16 char c1 = (char)reader.read(); 17 System.out.println(c1); 18 }catch(FileNotFoundException e) {///子类异常在父类异常前面 19 e.printStackTrace(); 20 }catch(IOException e) { 21 e.printStackTrace(); 22 }finally { 23 try { 24 if(reader != null) 25 reader.close(); 26 } catch (IOException e) { 27 // TODO Auto-generated catch block 28 e.printStackTrace(); 29 } 30 } 31 } 32 }
•注意事项
1. 即使 try 和 catch 块中存在 return 语句,finally 语句也会执行,是在执行完 finally 语句后再通过 return 退出。
2. finally 语句块只有一种情况是不会执行的,那就是在执行 finally 之前遇到了 System.exit(0) 结束程序运行。