第 7 章 异常处理
立体化教材计算机系列 — 《 Java 程序设计》 2 目 录 重点与难点点拨 经典练习题 异常处理机制 异常
立体化教材计算机系列 — 《 Java 程序设计》 3 本章知识重点 异 常异 常 异常处理机制 异常类 异常的类别 捕获异常 抛出异常 创建自定义异常 异常处理的作用
立体化教材计算机系列 — 《 Java 程序设计》 4 异常类 我们总是试图避免在软件程序中错误的发 生,但是百分之百没有错误的程序是不存 在的。无论怎样,如果我们能适当的处理 错误,将会极大的改善程序的可读性、可 靠性以及可维护性。 Java 编程语言使用异 常来处理错误。这章主要讲述在什么时候 和怎样使用异常来处理错误
立体化教材计算机系列 — 《 Java 程序设计》 5 异常处理程序的基本形式 method() throws ExceptionType2,ExceptionType3,……{ …… try { …… // 程序块 } catch (ExceptionType1 e) { ……// 对 ExceptionType1 的处理 } catch (ExceptionType2 e) { ……// 对 ExceptionType2 的处理,处理了一部分, throw(e); // 再抛出这个 “ 异常 ” 给上层的调用者 } …… finally {…… } }
立体化教材计算机系列 — 《 Java 程序设计》 6 异常对象 每个异常都是一个对象,它是 Throwable 类或 其它子类的实例. 当一个方法出现异常后便抛出一个 异常对象,该对象中包含有异常信息,调用这个对 象的方法可以捕获到这个异常并进行处理。 Throwable 类有两个标准子类: 错误类: java.lang.Error 错误 Error 类一般是指虚拟机相关的问题, 异常类: java.lang.Exception 异常 Exception 类则是指一些可以被捕获且可能恢复 的异常情况,如数组下标越界
立体化教材计算机系列 — 《 Java 程序设计》 7 Java 异常类的继承关系 Exception 异常又分为 RuntimeException 和 non- RuntimeException 两大类异常。
立体化教材计算机系列 — 《 Java 程序设计》 8 异常实例 异常实例 设定一个名称为 isLegal 的变量来检查数据是否合法,如果数据大于 0 时, 返回合法值,否则视为不合法,抛出 “ 异常 ” 。 int isLegal(int dt) throws LowZeroException { // 这种定义本文中均称为方 法与 “ 异常 ” 通过 throws 建立了关联 if(dt>=0){ return data; } else throw new LowZeroException(); } /* 自已写的异常类,继承自 Exception*/ class LowZeroException extends Exception { public LowZeroException(){ super(); }
立体化教材计算机系列 — 《 Java 程序设计》 9 异常的类别 在实际的程序开发中,异常无处不在,并且种类繁 多。区分什么情况下会出现什么样的异常是十分必 要的。 两个不同的角度来区分异常的种类: 异常发生的原因以 编译时对异常的检查。
立体化教材计算机系列 — 《 Java 程序设计》 10 异常的类别种类 Java 虚拟机所检测到的非正常的执行状态,一 般来说这些状态在编码的时候比较难以检测, 直到运行的时候才会暴露出来。 是 Java 语言中具有 throw 关键字的语句被执行 的时候 异步异常
立体化教材计算机系列 — 《 Java 程序设计》 11 无论是 Java 的 API 中定义的诸多异常类还是我 们自己定义的异常类 ( 自定义异常在下面本 章后面有详细的说明 ) ,根据编译器对异常 的检查情况,又可以分为可检测异常和不 可检测异常两种 异常的类别 异常的类别
立体化教材计算机系列 — 《 Java 程序设计》 12 可检测异常 常见的可检测异常有: ClassNotFoundException;// 没有找到指定类的定义 IOException;// 指示产生某种输入 / 输出异常。 FileNotFoundException;// 文件没有找到异常。 ArithmeticException
立体化教材计算机系列 — 《 Java 程序设计》 13 异常处理机制 捕获异常 抛出异常 创建自定义异常 异常处理的作用
立体化教材计算机系列 — 《 Java 程序设计》 14 捕获异常 Java 的异常处理是通过 5 个关键词来实现的: try 、 catch 、 throw 、 throws 和 finally 和所有的捕获异常程序一样,第一步是用 try 关键字 选定监控异常的代码范围,然后在这段程序之后使用 catch 关键字捕获异常,每个 try 代码块可以使用多个 catch 代码块来对应,而 catch 语句需要指名它所捕获 的异常的类型名。
立体化教材计算机系列 — 《 Java 程序设计》 15 捕获异常实例 isLegal 方法用来判断输入 int 类型的参数 iData 是否合法,如果合 法,便将合法的返回参数赋值给 data ,如果不合法,则抛出某 种异常。 异常抛出后,我们在捕获模块 (catch) 的大括号中打印 出错误 int MyMethod(int iData){ int data = 0; try { int data = isLegal(iData); } catch(xException e){ System.out.println(" 发生数据错误! "); } return data; }
立体化教材计算机系列 — 《 Java 程序设计》 16 抛出异常 抛出异常 若在 try 块中抛出的异常没有能够捕获它的 catch 块 ,或捕获这个异常但不想立即处理,则 Java 将退 出这个方法,并将其返回到上一级处理,如此不 断地递归向上直到最外一级。同时,在方法的声 明中要指定方法中可能产生的异常,使这个方法 的调用者准备好处理这种异常的代码,这种类型 的异常在此方法的调用者中得到了处理。调用者 可能自己处理这种异常,也可能将这个异常放给 它的调用者。异常就这样逐级上溯,直到找到处 理它的代码为止。如果没有任何代码来捕获并处 理这个异常, Java 将结束这个程序的执行
立体化教材计算机系列 — 《 Java 程序设计》 17 抛出异常的情况 Java 可能会抛出异常的情况包括:调用的方法抛出了 异常、检测到了错误并使用 throw 语句抛出异常、 程序代码有错误,从而导致异常,比如数组越界错 误、 Java 运行时刻系统产生内部错误。当前两种异 常发生时,应该告诉使用这个方法的人,此方法强 迫 Java 抛出异常。因为任何抛出异常的方法都是导 致程序死亡的陷阱,如果没有任何代码来处理方法 抛出的异常,就会导致程序结束
立体化教材计算机系列 — 《 Java 程序设计》 18 抛出异常步骤 确定异常类 创建异常类的实例 抛出异常
立体化教材计算机系列 — 《 Java 程序设计》 19 抛出异常实例 public class ExceptionUse { // 可能会抛出异常类的方法 public static void throwException() throws Exception { System.out.println(" 下面产生一个 Io 异常并将其抛出! "); // 抛出异常 throw new RuntimeException("MyException"); } public static void main(String [] args) { try { throwException(); } // 捕获异 catch(Exception re) { System.out.println(" 捕获 Io 异常: "+re); }
立体化教材计算机系列 — 《 Java 程序设计》 20 程序的输出结果 代码在 main() 方法中调用了 throwException() 方法,此方法 的声明中可以看到,它可能会抛出 IoException 异常。再看 此方法的定义,它使用 new 运算符实例化了一个 RuntimeException 类,并使用 throw 语句将其抛出。调用这 个方法后,异常被抛出, catch 语句进行捕获,并打印出异 常信息
立体化教材计算机系列 — 《 Java 程序设计》 21 创建自定义异常 创建自定义异常 现实世界是非常复杂的,常常会有一些特殊的约束 要求。例如我们制作一个统计河堤水位的软件, 水位过高的时候,对程序本身只是一个较大的数 字而已,并不会引发 Java 类库中的异常;但对于 现实中的情况,水位过高就是一个致命的异常。 这种情况下, Java 类库中的异常处理类已经不能 满足要求,我们需要抛出一个新的异常来提示过 高的水位:一个自己定义的异常
立体化教材计算机系列 — 《 Java 程序设计》 22 自定义语法 这里的 extends Exception 就是我们定义的这个异 常类是从 java 类库中的 Exception 这个类派生的, 也就是说,我们自定义的异常类可以拥有 Exception 这个类的全部的内容,另外,还可以再写一些我 们需要的内容在里面 创建自己的异常类非常的简单,可以用下面的声 明语言来定义: class 自定义异常名 extends Exception{…}
立体化教材计算机系列 — 《 Java 程序设计》 23 自定义异常实例一 假如我们需要抛出一个提示水位过高的异常,我们 可以写一个像下面这样的异常类 class MyException extends Exception { private int i; MyException(int a){ i = a; } public String toString() { return “ 水位过高 ”; }
立体化教材计算机系列 — 《 Java 程序设计》 24 自定义异常实例二 综合前面几节的知识,我们写一个抛出这个异常 的程序来测试一下这个自定义的异常类,同样的 还在这个类中,建立一个抛出这个异常的方法: Static void method(int a) throws MyException {// 声明这个方法会抛出 MyException 异常 If(a > 10) throw new MyException(a); }// 主动抛出 MyException(a)
立体化教材计算机系列 — 《 Java 程序设计》 25 自定义异常实例三 自定义异常实例三 当我们调用类 CatchDemo 中的静态方法 method (int a) 的时候,如果我们将大于 10 的参数赋值给 method 方法的时候,就会抛出我们上面写的水位 过高的异常。除了需要一个抛出异常的方法,运 行这个方法还需要在 main 方法中调用这个方法: Public static void main(string args[]){ try { method(11); }Catch(MyExceptin e){ System.out.println(e.toSring()); }
立体化教材计算机系列 — 《 Java 程序设计》 26 实例四 运行上面的程序,在控制台的输出界面中, 我们可以观察到下图的结果: 综上所述,当提供一些特定的功能用 Java 类时,需 要保证类之间有良好的关系,而且类之间的接口易 于理解和实现。对于异常类一样,可以定义新的异 常类。创建自己的异常类更便于维护和管理
立体化教材计算机系列 — 《 Java 程序设计》 27 异常处理的作用 在传统的非面向对象的编程语言中,并没有一个规 范和稳定的错误处理机制,编程者必须考虑到在程 序中可能出现的各种问题,并且自己定义一种可以 表示异常信息的方式 最常见的方式就是使用方法返回值进行处理。编写 返回一个执行结果或者状态代码的方法,调用者根 据返回的执行结果状态代码判断运行结果的正常或 者失败
立体化教材计算机系列 — 《 Java 程序设计》 28 异常处理的缺点 假如状态代码返回一个错误的状态代码,则进行相 应的处理,显示一个错误页面或错误信息。通过返 回值进行处理的方法是有效的,但有许多不足之处 对于编程人员来说,增加了他们的负担。对于编 写的程序来说,则有以下几个缺点: 出错处理不规范,降低了程序的可读性,程序复 杂,可靠性差,返回信息有限, 返回代码标准化 困难
立体化教材计算机系列 — 《 Java 程序设计》 29 异常处理的优点 异常处理的方式和传统的方式有所不同,当一个方 法引发一个异常之后,可以将异常抛出,由该方法 的直接或间接调用者处理这个异常。这就是常说的 catch-throw( 捕获 - 抛出 ) 方式 采用这种处理方式具有以下几个优点: 错误的处理变得规范化,把错误代码与常规代码分 开,可以在 catch 中传播错误信息,可以对错误类型 分组,方便定位错误和维护
立体化教材计算机系列 — 《 Java 程序设计》 30 经典练习题 ㈠填空题 ⑴ throw 语句的作用是 ____ 。 ⑵ Exception 又分为 ____ 和 ____ 异常。 ⑶ Java 中,异常分为 ____ 和 ____ 两类。 ⑷ Throwable 类有两个重要子类: ___ 和 ___ 。
立体化教材计算机系列 — 《 Java 程序设计》 31 ⑸下面程序段的执行结果是 _____ 。 public class Test{ public static void main(String[] args) { try{ return;} finally{System.out.println("Finally"); } 经典练习题
立体化教材计算机系列 — 《 Java 程序设计》 32 ㈡选择题 ⑴异常产生的原因很多,常见的有 ( ) 。 A. 程序设计本身的错误 B. 程序运行环境的改变 C. 软、硬件设置的错误 D. 以上都是 ⑵ ( ) 是除 0 异常。 A.RuntimeException B.ClassCastException C.ArithmeticException D.ArrayIndexOutOffBoundException 经典练习题
立体化教材计算机系列 — 《 Java 程序设计》 33 ⑶下面 ( ) 不是使用异常处理的原因。 A. 将错误处理程序与正常程序流分开,增加程序的可读性 B. 可以容易的指出异常在何处处理 C. 减轻程序员处理异常的任务 D. 增加语言的复杂机制 ⑷所有异常继承类都继承 ( ) 类。 A.Java.io.Exception B.Java.lang.Throwable C.Java.lang.Exception D.Java.lang.Error 经典练习题
立体化教材计算机系列 — 《 Java 程序设计》 34 ⑸下列不是用来捕获处理异常的关键字是 ( ) 。 A.throws B.try C.catch D.finally ⑹在抛出异常时,会自动调用这个异常的 ( ) 方法。 A.clone() B.getMessage() C.fillInStackTrace() D.toString() 经典练习题
立体化教材计算机系列 — 《 Java 程序设计》 35 ㈢编程题 编写一个能通过编译但是运行时会出现 ArithmeticException 异常的程序。 经典练习题
立体化教材计算机系列 — 《 Java 程序设计》 36 再 见