资源预览内容
第1页 / 共55页
第2页 / 共55页
第3页 / 共55页
第4页 / 共55页
第5页 / 共55页
第6页 / 共55页
第7页 / 共55页
第8页 / 共55页
第9页 / 共55页
第10页 / 共55页
亲,该文档总共55页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
第5章 Java例外处理,5.1 异常的基本概念 5.2 异常的处理机制 5.3 异常类的类层次,5.1 异常的基本概念,异常(Exception)是程序执行过程中出现的非正常事件,即各种意外情况。比如说: 用户输入出错 所需文件找不到 运行时磁盘空间不够 内存不够, 算术运算错 (数的溢出,被零除) 数组下标越界 当Java程序出现以上的错误时,就会在所处的方法中产生一个异常对象。这个异常对象包括错误的类型,错误出现时程序的运行状态以及对该错误的详细描述。下面我们先看一个简单的例子。,例5.1 public class ExceptionDemo public static void main(String args) int x=100; System.out.println(“The result is“+x/10); System.out.println(“Divided by zero: “+x/0); ,当我们对其编译后运行时,其对应的结果如下: c:jbuilder3javabinjava Exception Demo The result is10 Exception in thread “main“ java.lang.Arithmetic Exception: / by zero at Exception Demo.main(Exception Demo.java:5) 其意思是说,本程序执行到语句“System.out.println (“Divided by zero: “+x/0)”时,系统会抛出一个例外,该例外在Java中定义为Arithmetic Exception (即属于算术运算例外)。,5.2 异常的处理机制,我们知道,一旦程序在执行的过程中出现异常,往往有两种处理方式: (1) 当程序出现错误的时候,系统将终止程序的运行,如例5.1。在Java中这是属于运行异常,用户不加干预,完全交由系统对其进行处理。,(2) 当程序出现错误时,采用捕捉抛出(catch-throw)的面向对象编程方式。该种方式是当程序运行出错时,系统和程序抛出各种标准类型的错误,程序捕捉该错误并进行相应处理。由于异常均以标准的形式提供,使得程序员能以统一的方式对异常进行处理。 通常,Java的出错与异常处理采用“try, catch, throws”语句来实现,下面我们分别加以介绍。,5.2.1 异常的直接捕获与处理:try-catch try-catch语句构成Java对异常直接处理的基本处理单元,其一般语法如下: try program where errors may arise catch (ExceptionClass1 c) what to do with it catch (ExceptionClass2 d) what to do with it ,上述用法中,可能出现异常的语句放在由try语句所括住的程序块中。try块管理其所包含的语句并定义与之相关的异常指针范围,它的后面必须至少接一个catch语句。catch语句块负责处理各对应类型的异常。 实际编程过程中,如果我们对程序代码可能出现的异常不进行捕获,Java的编译环境就拒绝执行,并要求用户对其作出处理。看下例:,例5.2 import java.io.*; public class ExceptionDemo1 public static void main(String args) int i; File Input Stream fis=new File Input Stream(“file_in.txt“);,File Out put Stream fos=new File Out put Stream(“file_out.txt“); while(i=fis.read()!=-1) fos.write(i); fis.close(); fos.close(); 例5.2只是一个简单的文件输入/输出程序。该程序中定义了一个文件输入流和文件输出流,然后通过它们进行文件的拷贝。,当上述程序进行编译的时候,结果如下: c:JBUILD1javabinjavac ExceptionDemo1.java ExceptionDemo1.java:5: Exception java.io.FileNotFoundException must be caught, or it must be declared in the throws clause of this method. FileInputStream fis=new FileInputStream(“file_in.txt“); ExceptionDemo1.java:7: Exception java.io.IOException must be caught, or it must be declared in the throws clause of this method. while(i=fis.read()!=-1) 2 errors,系统异常信息告诉我们,两种异常程序员必须捕获,即File Not FoundExcetion和IOException。对例外进行处理时,用户往往想知道异常的具体信息,我们可利用异常父类Throwable中提供的方法get Message()得到有关异常事件的信息。方法print Stack Trace()可用来跟踪异常事件发生时执行堆栈的内容。这样,例5.2可改写为,例5.3 import java.io.*; public class ExceptionDemo1 public static void main(String args) int i; try FileInputStream fis=new FileInputStream(“file_in.txt“); FileOutputStreamfos=new FileOutputStream(“file_out.tx t“); while(i=fis.read()!=-1) fos.write(i);,fis.close(); fos.close(); catch (FileNotFoundException e) System.out.println(“The error is: “+e.getMessage(); e.printStackTrace(System.out); catch(IOException e) System.out.println(“The error is: “+e); ,程序中增加了对例外的处理语句后,就顺利通过了编译。catch语句的执行顺序是先捕获最特殊的异常,之后逐渐一般化,因为,IOException是FileNotFoundException的父类。 Java允许用户捕获实际需要捕获的异常类的超类,所以,一个catch语句就可以同时捕获多种异常。这样,例5.3中的try-catch语句又可以改写为 try . catch(Exception e) System.out.pritnln(“The error is: “+e.getMessage();,因为Exception类是FileNotFoundException类和IOException类的超类,所以对一段可能抛出大量不同类型的异常的程序来说,逐个捕获处理异常可能会较繁琐,而仅仅捕获它们父类的异常则会较方便。实际使用中,需要避免捕获最一般的异常类型(即超类Exception),因为捕获最一般的异常使得用户往往不能确切地判断异常的具体类型并作出相应的处理。针对例5.3,如果try-catch语句写为,try . catch(Exception e) System.out.pritnln(“The error is: “+e.getMessage(); catch(IOException e) System.out.println(“The error is: “+e); catch (FileNotFoundException e) System.out.println(“The error is: “+e.getMessage(); e.printStackTrace(System.out); ,则该异常的后两个catch捕获语句会始终匹配不到,造成编译器的混乱。所以说,捕获异常的顺序是和catch语句顺序相关的,希望读者注意它的用法。 与异常处理语句try-catch相关的另一条语句是finally语句。它为例外处理提供一个统一的出口,使得在控制流转到程序的其他部分以前,能够对程序的状态作统一的管理,比如关闭文件或释放其他系统资源。实际使用中finally紧接于try-catch语句的最后一个catch块,基本语法如下:,try program where errors may arise catch (ExceptionClass1 c) what to do with it catch (ExceptionClass2 d) what to do with it finally .,finally语句的执行是非常决断的、无条件的执行的。无论是否出现异常,也不管出现哪一种异常或即使try语句块中包含有return、break、continue等语句,均须执行finally语句块所包含的语句。这就是说,finally语句的作用与C+中类的析构函数相似。比如在例5.3中,我们打开了文件file_in、file_out进行读/写操作,如果产生了异常,就可能需中断,此时,对应的文件有可能无法正常关闭,这会对文件造成破坏。但使用finally语句后,就可把方法中的所有善后工作作统一处理,既增强程序的可读性,又避免了对系统或文件的损害。所以,例5.3可改写为,例5.4 import java.io.*; public class ExceptionDemo1 public static void main(String args) int i; try FileInputStream fis=new FileInputStream(“file_in.txt“); FileOutputStreamfos=new FileOutputStream(“file_out.txt“); while(i=fis.read()!=-1) fos.write(i);,fis.close(); fos.close(); catch (FileNotFoundException e) System.out.println(“The error is: “+e.getMessage(); e.printStackTrace(System.out); catch(IOException e) ,System.out.println(“The error is: “+e); finally if(fis!=null|fos!=null); System.out.println(“Now closing file“); fis.close(); fos.close(); ,5.2.2 异常的间接声明抛弃 当在程序或代码块中出现异常时,Java语法要求要么对其捕获,要么在方法定义中用关键字throws声明异常类型并间接将其抛出,交给其调用者来进行处理。也就是说,异常对象可以从调用栈向后传播,直到有合适的方法对其进行捕获为止。例如: public type method Name (args If Any) throws Exc
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号