1.异常基本概念
a). 异常产生的条件, 或者称为异常情况。在Java代码中哪些是异常情况呢? 例如:
i. 整数相除运算中,分母为0;
ii. 通过一个没有指向任何具体对象的引用去访问对象的方法;
iii. 使用数组长度作为下标访问数组元素;
iv. 将一个引用强制转化成不相干的对象;
等等;
b). 异常会改变正常程序流程;
异常产生后,正常的程序流程被打破了,要么程序中止,要么程序被转向异常处理的语句;
c). 当一个异常的事件发生后,该异常被虚拟机封装形成异常对象抛出。
d). 用来负责处理异常的代码被称为异常处理器
f). 通过异常处理器来捕获异常
2.try…catch语句
在Java语言中,用try...catch语句来捕获处理异常。格式如下:
try {
可能会出现异常情况的代码;
} catch(异常类型 异常参数) {
异常处理代码
} catch(异常类型 异常参数) {
异常处理代码
}
1). 如果try代码块中没有抛出异常,try代码块中语句会顺序执行完,catch代码块内容不会被执行;
2).如果try代码块中抛出catch代码块所声明的异常类型对象,程序跳过try代码块中接下来代码,直接执行catch代码块中对应内容;
a. 可以存在多个catch代码块,究竟执行哪个,看抛出的异常对象是否是catch代码块中异常类型;
b. 异常只能被一个异常处理器所处理, 不能声明两个异常处理器处理相同类型的异常;
c. 多个catch语句块所声明的异常类型不能越来越小;
d. 不能捕获一个在try语句块中没有抛出的异常;
3).如果try代码块中抛出catch代码块未声明的异常类型对象,异常被抛给调用者;哪个调用了这段语句块哪个负责处理这个异常;
3.finally语句
任何情况下都必须执行的代码,即使之前代码存在return语句
4.异常层级关系
所有异常类的祖先类为java.lang.Throwable类。它有两个直接的子类:
1).Error类:表示仅靠程序本身无法恢复的严重错误,比如内存空间不足,或者Java虚拟机的方法调用栈溢出。在大多数情况下,遇到这样的错误时,建议让程序终止。
2). Exception类:表示程序本身可以处理的异常。Exception还可以分为两种:运行时异常和受检查异常。
a).运行时异常RuntimeException类及其子类都被称为运行时异常,这种异常的特点是Java编译器不会检查它,也就是说,当程序中可能出现这类异常时,即使没有用try...catch语句捕获它,也没有用throws子句声明抛出它,还是会编译通过。例如divide()方法的参数b为0, 执行a/b操作时会出现ArithmeticException异常,它属于运行时异常,Java编译器不会检查它。
b). 受检查异常除了RuntimeException及其子类以外,其他的Exception类及其子类都属于受检查异常(Checked Exception)。 这种异常的特点是Java编译器会检查它,也就是说,当程序中可能出现这类异常时,要么用try...catch语句捕获它,要么用throws子句声明抛出它,否则编译不会通过。
5. 异常声明和处理
1). 使用throw声明代码会倒致异常;
2). 使用try-catch-finally语句结构处理或在方法声明上声明throws继续抛出;
异常处理语句的语法规则:
i). try代码块不能脱离catch代码块或finally代码块而单独存在。try代码块后面至少有一个catch代码块或finally代码块。
ii). try代码块后面可以有零个或多个catch代码块,还可以有零个或至多一个finally代码块。如果catch代码块和finally代码块并存,finally代码块必须在catch代码块后面。
iii). try代码块后面可以只跟finally代码块。
iv). 在try代码块中定义的变量的作用域为try代码块,在catch代码块和finally代码块中不能访问该变量。
v). 当try代码块后面有多个catch代码块时,Java虚拟机会把实际抛出的异常对象依次和各个catch代码块声明的异常类型匹配,如果异常对象为某个异常或其子类的实例,就执行这个catch代码块,而不会再执行其他的catch代码块。
vi). 如果一个方法可能出现受检查异常,要么用try...catch语句捕获,要么用throws子句声明将它抛出。
vii). throw语句后面不允许紧跟其它语句,因为这些语句永远不会被执行。
6.自定义异常
可以定义自己的异常类,继承Exception受检时异常,或者继承RuntimeException运行时异常,必须人工抛出;
7. 异常调用栈
1.异常处理时所经过的一系列方法调用过程被称为异常调用栈。
1). 异常的传播,哪个调用,哪个处理;
a. 异常情况发生后,发生异常所在的方法可以处理;
b. 异常所在的方法内部没有处理,该异常将被抛给该方法调用者,调用者可以处理;
c. 如调用者没有处理,异常将被继续抛出;如一直没有对异常处理,异常将被抛至虚拟机;
2). 如果异常没有被捕获,那么异常将使你的程序将被停止。异常产生后,如果一直没有进行捕获处理,该异常被抛给虚拟机。程序将被终止。
3). 经常会使用的异常API
getCause():返回类型是Throwable,该方法获得Throwable的
异常原因或者null。
getMessage():获得具体的异常出错信息,可能为null。
printStatckTrace():打印异常在传播过程中所经过的一系列方
法的信息,简称异常处理方法调用栈信息;在程序调试阶段,此方法可用于跟踪错误。
2.常见的未检查的异常RuntimeException有哪些?分别代表什么含义?
1). java.lang.ArithmeticException
算术异常 如:除0;
2). java.lang.NullPointerException
空指针引用 如:没初始化一个References便使用;
3). java.lang.ArrayIndexoutofBoundsException
数组越界 如:调用一个有十个元素的Array的第十一个元素的内容;
4). java.lang.SecurityException
违反了java定义的安全规则
5). java.lang.NumberFormatException
数据格式异常 如:Integer.parseInt("a");
6). java.lang.NegativeArraySizeException 数组长度为负数异常