第七章异常 本模块讲述建立在Java编程语言中的错误处理装置。 The Jaa Programm ing La Ivoire gU Communication 第一节相关问题 讨论一下述问题与本模块中的材料相关: 在大部分编程语言中,如何解决运行时错误? 第二节目的 本模块学习结束后,能够 定义异常 使用try, catch和 finally语句 描述异常分类 开发程序来处理自己的异常 第三节异常 异常类定义程序所遇到的轻微错误 发生下列情况时,会出现异常 想打开的文件不存在 网络连接中断 受控操作数超出预定范围 非常感兴趣地正在装载的类文件丢失 错误类定义严重的错误条件 73.1介绍
第七章 异 常 本模块讲述建立在 Java 编程语言中的错误处理装置。 第一节 相关问题 讨论—下述问题与本模块中的材料相关: - 在大部分编程语言中,如何解决运行时错误? 第二节 目 的 本模块学习结束后,能够: - 定义异常 - 使用 try,catch 和 finally 语句 - 描述异常分类 - 开发程序来处理自己的异常 第三节 异 常 异 常 异常类定义程序所遇到的轻微错误 发生下列情况时,会出现异常: 想打开的文件不存在 网络连接中断 受控操作数超出预定范围 非常感兴趣地正在装载的类文件丢失 错误类定义严重的错误条件 7.3.1 介绍
什么是异常?在Java编程语言中,异常类定义程序中可能遇到的轻微的错误条件。可以写代码来处理异常并继续程 序执行,而不是让程序中断 在程序执行中,任何中断正常程序流程的异常条件就是错误或异常。例如,发生下列情况时,会出现异常: 想打开的文件不存在 网络连接中断 受控操作数超出预定 非常感兴趣地正在装载的类文件丢失 在Java编程语言中,错误类定义被认为是不能恢复的严重错误条件。在大多数情况下,当遇到这样的错误时,建议 让程序中断 Java编程语言实现C艹异常来帮助建立弹性代码。在程序中发生错误时,发现错误的方法能抛出一个异常到其调用 程序,发出已经发生问题的信号。然后,调用方法捕获抛出的异常,在可能时,再恢复回来。这个方案给程序员一个写 处理程序的选择,来处理异常。 通过浏览API,可以决定方法抛出的是什么样的异常。 732实例 考虑一下 HelloWorld.java程序版本的简单扩展,它通过信息来循环 1. public class Helloworld t 2. public static void main (String args [])i 3456789 String greetings [ =i w Hello world # No,I mean it! " HELLO WORLD !I System. out. println (greetings [i])i 1++; 正常情况下,当异常被抛出时,在其循环被执行四次之后,程序终止,并带有错误信息,就象前面所示的程序那样。 1. c: \student\> java Helloworld 2. Hello world o,I mean it! 4. HELLO WORLD! I 5. java.lang Ar rayIndexOu tofBounds Exception: 3 6 at HelloWorld. main(HelloWorld. java: 12) 异常处理允许程序捕获异常,处理它们,然后继续程序执行。它是分层把关,因此,错误情况不会介入到程序的正常流 程中。特殊情况发生时,在与正常执行的代码分离的代码块中被处理。这就产生了更易识别和管理的代码
97 什么是异常?在 Java 编程语言中,异常类定义程序中可能遇到的轻微的错误条件。可以写代码来处理异常并继续程 序执行,而不是让程序中断。 在程序执行中,任何中断正常程序流程的异常条件就是错误或异常。例如,发生下列情况时,会出现异常: - 想打开的文件不存在 - 网络连接中断 - 受控操作数超出预定范围 - 非常感兴趣地正在装载的类文件丢失 在 Java 编程语言中,错误类定义被认为是不能恢复的严重错误条件。在大多数情况下,当遇到这样的错误时,建议 让程序中断。 Java 编程语言实现 C++异常来帮助建立弹性代码。在程序中发生错误时,发现错误的方法能抛出一个异常到其调用 程序,发出已经发生问题的信号。然后,调用方法捕获抛出的异常,在可能时,再恢复回来。这个方案给程序员一个写 处理程序的选择,来处理异常。 通过浏览 API,可以决定方法抛出的是什么样的异常。 7.3.2 实例 考虑一下 HelloWorld.java 程序版本的简单扩展,它通过信息来循环: 1. public class HelloWorld { 2. public static void main (String args[]) { 3. int i = 0; 4. 5. String greetings [] = { 6. "Hello world!", 7. "No, I mean it!", 8. "HELLO WORLD!!" 9. }; 10. 11. while (i < 4) { 12. System.out.println (greetings[i]); 13. i++; 14. } 15. } 16. } 正常情况下,当异常被抛出时,在其循环被执行四次之后,程序终止,并带有错误信息,就象前面所示的程序那样。 1. c:\student\> java HelloWorld 2. Hello world! 3. No, I mean it! 4. HELLO WORLD!! 5. java.lang.ArrayIndexOutOfBoundsException: 3 6. at HelloWorld.main(HelloWorld.java:12) 异常处理允许程序捕获异常,处理它们,然后继续程序执行。它是分层把关,因此,错误情况不会介入到程序的正常流 程中。特殊情况发生时,在与正常执行的代码分离的代码块中被处理。这就产生了更易识别和管理的代码
第四节异常处理 Java编程语言提供了一个来考虑哪个异常被抛出以及如何来恢复它的机制, 741try和 catch语句 try和 catch语句 1234567 // code that might throw a particular exception 3. catch (MyE ionType e) i //code to execute if a My Exception ype exception is thrown t catch (Exception e) t // code to execute if a general Exception exception is thrown 要处理特殊的异常,将能够抛出异常的代码放入try块中,然后创建相应的 catch块的列表,每个可以被抛出异常 都有一个。如果生成的异常与 catch中提到的相匹配,那么 catch条件的块语句就被执行。在try块之后,可能有许多 catch块,每一个都处理不同的异常。 1. try 2 / code that might throw a particular except ion 3. catch (MyException Type e)t // code to execute if a MyExceptionType exception is thrown 5. catch (Exception e)( 6.// code to execute if a general Exception exception is thrown 7.4.2调用栈机制 如果方法中的一个语句抛出一个没有在相应的try/ catch块中处理的异常,那么这个异常就被抛出到调用方法中。 如果异常也没有在调用方法中被处理,它就被抛出到该方法的调用程序。这个过程要一直延续到异常被处理。如果异常 到这时还没被处理,它便回到main0,而且,即使 mainO不处理它,那么,该异常就异常地中断程序 考虑这样一种情况,在该情况中 main o方法调用另一个方法(比如, first0),然后它调用另一个(比如, second0)。 如果在 second(中发生异常,那么必须做一个检查来看看该异常是否有一个 catch:如果没有,那么对调用栈( first0) 中的下一个方法进行检査,然后检査下一个( maino)。如果这个异常在该调用栈上没有被最后一个方法处理,那么就 会发生一个运行时错误,程序终止执行 7.43 finally语句 finally语句 1. try i startEaucet()i waterlawn(i 5. finall stopFaucet() finally语句定义一个总是执行的代码块,而不考虑异常是否被捕获。下述样板代码来自 Frank Yellin弗兰克叶林 的白皮书《Java中的低级安全》 1. try t startFaucet() waterland)i
98 第四节 异常处理 Java 编程语言提供了一个来考虑哪个异常被抛出以及如何来恢复它的机制。 7.4.1 try 和 catch 语句 try 和 catch 语句 1. try { 2. // code that might throw a particular exception 3. } catch (MyExceptionType e) { 4. // code to execute if a MyExceptionType exception is thrown 5. } catch (Exception e) { 6. // code to execute if a general Exception exception is thrown 7. } 要处理特殊的异常,将能够抛出异常的代码放入 try 块中,然后创建相应的 catch 块的列表,每个可以被抛出异常 都有一个。如果生成的异常与 catch 中提到的相匹配,那么 catch 条件的块语句就被执行。在 try 块之后,可能有许多 catch 块,每一个都处理不同的异常。 1. try { 2. // code that might throw a particular exception 3. } catch (MyExceptionType e) { 4. // code to execute if a MyExceptionType exception is thrown 5. } catch (Exception e) { 6. // code to execute if a general Exception exception is thrown 7. } 7.4.2 调用栈机制 如果方法中的一个语句抛出一个没有在相应的 try/catch 块中处理的异常,那么这个异常就被抛出到调用方法中。 如果异常也没有在调用方法中被处理,它就被抛出到该方法的调用程序。这个过程要一直延续到异常被处理。如果异常 到这时还没被处理,它便回到 main(),而且,即使 main()不处理它,那么,该异常就异常地中断程序。 考虑这样一种情况,在该情况中 main()方法调用另一个方法(比如,first()),然后它调用另一个(比如,second())。 如果在 second()中发生异常,那么必须做一个检查来看看该异常是否有一个 catch;如果没有,那么对调用栈(first()) 中的下一个方法进行检查,然后检查下一个(main())。如果这个异常在该调用栈上没有被最后一个方法处理,那么就 会发生一个运行时错误,程序终止执行。 7.4.3 finally 语句 finally 语句 1. try { 2. startFaucet(); 3. waterLawn(); 4. } 5. finally { 6. stopFaucet(); 7. } finally 语句定义一个总是执行的代码块,而不考虑异常是否被捕获。下述样板代码来自 Frank Yellin 弗兰克叶林 的白皮书《Java 中的低级安全》: 1. try { 2. startFaucet(); 3. waterLawn();
5. finally t stopFaucet ()i 在前面的例子中,即使异常在打开开关或给草地浇水时发生,开关也能被关掉。try后面的括号中的代码被称做保 护码 如果终止程序的 System, exit(方法在保护码内被执行,那么,这是 finally语句不被执行的唯一情况。这就暗示, 控制流程能偏离正常执行顺序,比如,如果一个 return语句被嵌λtry块内的代码中,那么, finally块中的代码应在 return前执行。 744重访前例 下面的例子是第169页 main o方法的重写。本程序以前的版本中产生的异常被捕获,数组索引重新设定,使下述程 序继续运行。 1. public static void main (String args []) 3. String greetings []=1 Hello world!" No I mean it! 5678 while (i< 4) 1 catch (ArrayIndexOut ofBoundsException e)t System. out. println("Re-setting Index Value ") System. out. println(" This is always printed") 16 当循环被执行时,下述在屏幕上出现的信息将改变 2. This is always printed 3. No, I mean it! 4. This is always printed 5. HELLO WORLD! I his is always printed 7. Re-setting Index value 8. This is always printed 第五节异常分类
99 4. } 5. finally { 6. stopFaucet(); 7. } 在前面的例子中,即使异常在打开开关或给草地浇水时发生,开关也能被关掉。try 后面的括号中的代码被称做保 护码。 如果终止程序的 System.exit()方法在保护码内被执行,那么,这是 finally 语句不被执行的唯一情况。这就暗示, 控制流程能偏离正常执行顺序,比如,如果一个 return 语句被嵌入 try 块内的代码中,那么,finally 块中的代码应在 return 前执行。 7.4.4 重访前例 下面的例子是第 169 页 main()方法的重写。本程序以前的版本中产生的异常被捕获,数组索引重新设定,使下述程 序继续运行。 1. public static void main (String args[]) { 2. int i = 0; 3. String greetings [] = { 4. "Hello world!", 5. "No, I mean it!", 6. "HELLO WORLD!!" 7. }; 8. while (i < 4) { 9. try { 10. System.out.println (greetings[i]); 11. } catch (ArrayIndexOutOfBoundsException e){ 12. System.out.println( "Re-setting Index Value"); 13. i = -1; 14. } finally { 15. System.out.println("This is always printed"); 16. } 17. i++; 18. } // end while() 19. } // end main() 当循环被执行时,下述在屏幕上出现的信息将改变。 1. Hello world! 2. This is always printed 3. No, I mean it! 4. This is always printed 5. HELLO WORLD!! 6. This is always printed 7. Re-setting Index Value 8. This is always printed 第五节 异常分类
在Java编程语言中,异常有三种分类。Java.lang. Throwable类充当所有对象的父类,可以使用异常处理机制将这 些对象抛出并捕获。在 Throwable类中定义方法来检索与异常相关的错误信息,并打印显示异常发生的栈跟踪信息。它 有 Error和 Exception两个基本子类,如下图所示: outofMemoryError StackOverflowerror Throwable ArithmeticException FuntimeException Exception IndexoutofBounds EOFException IOExceoti FileNotFoundException Throwable类不能使用,而使用子类异常中的一个来描述任何特殊异常。每个异常的目的描述如下: Eror表示恢复不是不可能但很困难的情况下的一种严重问题。比如说内存溢出。不可能指望程序能处理这样 的情况 Runtime Exception表示一种设计或实现问题。也就是说,它表示如果程序运行正常,从不会发生的情况。比如, 如果数组索引扩展不超出数组界限,那么, Array IndexOutOfBoundsException异常从不会抛出。比如,这也适 用于取消引用一个空值对象变量。因为一个正确设计和实现的程序从不出现这种异常,通常对它不做处理。这 会导致一个运行时信息,应确保能采取措施更正问题,而不是将它藏到谁也不注意的地方。 其它异常表示一种运行时的困难,它通常由环境效果引起,可以进行处理。例子包括文件未找到或无效URL异 常(用户打了一个错误的URL),如果用户误打了什么东西,两者都容易出现。这两者都可能因为用户错误而 出现,这就鼓励程序员去处理它们。 第六节共同异常 共同异常 ArithmeticException NullPointerException NegativeArraySizeException Array Indexoutof BoundsExcept iol SecurityException Java编程语言提供几种预定义的异常。下面是可能遇到的更具共同性的异常中的几种 ArithmeticException-整数被0除,运算得出的结果
100 在 Java 编程语言中,异常有三种分类。Java.lang.Throwable 类充当所有对象的父类,可以使用异常处理机制将这 些对象抛出并捕获。在 Throwable 类中定义方法来检索与异常相关的错误信息,并打印显示异常发生的栈跟踪信息。它 有 Error 和 Exception 两个基本子类,如下图所示: Throwable 类不能使用,而使用子类异常中的一个来描述任何特殊异常。每个异常的目的描述如下: - Error 表示恢复不是不可能但很困难的情况下的一种严重问题。比如说内存溢出。不可能指望程序能处理这样 的情况。 - RuntimeException 表示一种设计或实现问题。也就是说,它表示如果程序运行正常,从不会发生的情况。比如, 如果数组索引扩展不超出数组界限,那么,ArrayIndexOutOfBoundsException 异常从不会抛出。比如,这也适 用于取消引用一个空值对象变量。因为一个正确设计和实现的程序从不出现这种异常,通常对它不做处理。这 会导致一个运行时信息,应确保能采取措施更正问题,而不是将它藏到谁也不注意的地方。 - 其它异常表示一种运行时的困难,它通常由环境效果引起,可以进行处理。例子包括文件未找到或无效 URL 异 常(用户打了一个错误的 URL),如果用户误打了什么东西,两者都容易出现。这两者都可能因为用户错误而 出现,这就鼓励程序员去处理它们。 第六节 共同异常 共同异常 - ArithmeticException - NullPointerException - NegativeArraySizeException - ArrayIndexoutofBoundsException - SecurityException Java 编程语言提供几种预定义的异常。下面是可能遇到的更具共同性的异常中的几种: - ArithmeticException—整数被 0 除,运算得出的结果