异常处理
Java的异常处理(excption-handling)机制是个简洁、轻量化的执行期间例外状况处理方式。它让你能够将处理错误状况的程序代码摆在一个容易阅读的位置。这要依赖你已经知道所调用的方法是有风险的(也就是说方法可能会产生异常),因此你可以编写出处理此可能性的程序代码。如果你知道调用某个方法可能会有异常状况,你就可以预先准备好对问题的处理程序,甚或是从错误中恢复。
知道某个方法是否会抛出异常的方式是看该方法的声明中有没有throws语句。
try/catch块
try/catch块告诉编译器你确实知道调用的方法有风险,并且也已经准备好处理它。
流程控制
- try中内容成功,不执行catch;
- try中不成功,跳过try中剩下部分,直接执行catch;
finally:无论如何都要执行的部分
- 如果try块失败了:抛出异常,流程马上转移到catch块。catch完成后执行finally块。
- 如果try块成功:跳过catch块,执行finally块。
- 若try或catch块有return指令,finally块还是会执行,流程会调到finally然后再回到return指令。
异常
异常是一种Exception类型的对象。
因为它是对象,所以catch住的也是对象。下面的程序代码中catch的参数是Exception类型的ex引用变量:
try {
//危险动作
} catch(Exception ex) {
//尝试恢复
}
写在catch块中的程序必定与所抛出的异常有关。
抛出异常
当你的程序代码调用有风险的方法时(也就是声明有异常的方法),就是该方法抛出异常。
有风险、会抛出异常的程序代码:
public void takeRisk() throws BadException { //必须要声明它会抛出BadException
if (abandonAllHope) {
throw new BadException(); //创建Exception对象并抛出
}
}
调用该方法的程序代码:
public void crossFingers() {
try {
anObject.takeRisk();
} catch (BadException ex) {
System.out.println("Aaargh!");
ex.printStackTrace(); //调用此方法列出有用的信息
}
}
方法可以抓住其他方法所抛出的异常。异常总是丢回给调用方。
会抛出异常的方法必须要声明它有可能会这么做。
抛出一个以上异常
方法可以抛出多个异常,但在该方法的声明里必须要含有全部可能的检查异常(若两个或两个以上的异常有共同的父类时,可以只声明该父类):
public class Laundry {
public void doLaundry() throws PantsException, LingerieException {
//有可能抛出两个异常的程序代码
}
}
public class Foo {
public void go() {
Laundry laundry = new Laundry();
try {
laundry.doLaundry();
} catch(PantsException pex) {
//恢复程序代码
} catch(LingerieException lex) {
//恢复程序代码
}
}
}
异常也是多态的
如果处理各子类型异常方式不同,要单独编写,如果相同,则可以编写一个父类型的处理方式。
在处理多态问题时要把子类异常写在前面,因为一旦程序catch了父类异常,就不会再管其他子类异常。
不想处理异常
方法:继续抛出异常
小结:两种处理异常的方式
异常处理规则
- catch与finally不能没有try;
- try与catch之间不能有程序;
- try一定要有catch或finally;
- 只带有finally的try必须要声明异常;