第11章异常处理异常处理•引入例外机制•Java的例外处理–例外的抛出、捕获与处理•自定义例外•使用finally第11章异常处理对错误的处理•程序执行的错误•处理错误–向用户通知错误–保存全部工作–让用户适当地退出程序•例外处理–JAVA检测和报告错误的机制第11章异常处理异常•为了加强程序的鲁棒性(强壮性,robust),程序设计时,必须考虑到可能发生的异常事件并做出相应的处理•例6-1–虽然程序的鲁棒性加强了,但结构臃肿,大量的错误处理代码混杂在程序中,可读性差。目标程序也会增大许多–出错返回信息量太少,无法更确切的了解错误状况或原因。特别是,当出现上述语句没包含的情况时,程序将束手无策第11章异常处理处理错误的方式•函数式编程中,直接检测调用函数返回值以确定错误内容,存在问题–检测错误返回的编码工作量大,逻辑上复杂–返回的错误信息有限,无详细的位置性质等•例外处理–throws,使不能正常结束的方法抛出一个封装了错误信息的对象-例外–使用例外处理程序处理异常错误第11章异常处理Java异常处理机制•预定义了Exception类。在Exception类中定义了程序产生异常的条件•简化了代码的编写。常见的异常也可以统一处理,提高了效率,代码重用率高•允许程序员自己编写特殊的异常处理程序,以满足更独特的需要第11章异常处理抛出和捕获•方法的运行过程中,如果发生了异常,称程序产生了一个异常事件,相应地生成异常对象。生成异常对象并把它提交给运行时系统的这一过程称为抛出(throw)异常•异常发生时,Java运行时系统从生成对象的代码块开始进行回溯,找到包含相应异常处理的方法,并把异常对象交给该方法处理,这一过程称为捕获(catch)•例6-2用异常处理方式来重写例6-1第11章异常处理异常机制的优点•把异常处理代码从常规代码中分离出来,增加了可读性,方便修改•按异常类型和差别进行分组,即从预定义的类Exception中派生自己的子类,对无法预测的异常也可以进行捕获和处理,克服了传统方法中错误信息有限的问题•异常的处理借助于调用堆栈按先近后远的原则进行第11章异常处理异常传播方式method1method2method3method4探测抛出异常传递捕获处理异常调用第11章异常处理11.1.1异常处理机制的结构Java中引入了异常和异常类,并且定义了很多异常类。每个异常类代表一类运行错误,类中包含了该运行错误的信息和处理错误的方法等内容。每当Java程序运行过程中发生一个可识别的运行错误时,系统都会产生一个相应异常类的对象,并由系统中相应的机制来处理,以确保不会产生死机、死循环或其他对操作系统有损害的结果,从而保证了整个程序运行的安全性。第11章异常处理图11.1异常处理机制结构程序运行时期使用try-catch-finally语句自行处理由预设处理方法加以处理是否自行处理异常第11章异常处理在Java程序中,当程序运行过程中发生异常时,可采用如图11.1所示的两种方式处理异常:一是由Java异常处理机制的预设处理方法来处理,即一旦程序发生异常,程序就会被终止并显示一些错误信息给用户;二是使用Java语言提供的try-catch-finally语句自行处理异常。这种方式的优点很多,其中最主要的优点是将处理异常的代码与程序代码的主线分离开来,增强了程序的可读性;其次是可减少中途终止程序运行的可能性。第11章异常处理【示例程序c11_1.java】系统自动抛出异常。publicclassc11_1{publicstaticvoidmain(String[]args){inta,b,c;a=67;b=0;c=a/b;System.out.println(a+/+b+=+c);}}运行结果:Exceptioninthreadmainjava.lang.ArithmeticExcption:/byzeroAtc11_1.main(c11_1.java:8)第11章异常处理异常层次结构第11章异常处理使用异常机制情况•当方法因为自身无法控制的原因而不能完成其任务•文件不存在,网络连接无法建立等•处理在方法、类库、类中抛出的异常–如FileInputStream.read产生IOException;•在大的项目中采用统一的方式处理异常时–编写文字处理器一类的程序等;•不经常发生但却可能发生的故障第11章异常处理异常示例•简单扩展前面使用过的程序1-1的HelloWorldApp.java程序,循环打印一些信息。程序执行到第4次循环时,会发生异常代码见程序6-1第11章异常处理在Java语言中所有的异常类都继承自java.lang.Throwable类。Throwable类有两个直接子类:一个是Error子类,它包含Java系统或执行环境中发生的异常,这些异常是用户无法捕捉到的异常;另一个是Exception类,它包含了一般性的异常,如I/O异常,SQL异常,这些异常是用户可以捕捉到的异常,可以通过产生它的子类来创建自己的异常处理。下面分别论述。第11章异常处理第11章异常处理2.java.io包中的异常第11章异常处理3.java.awt包中的异常第11章异常处理4.java.net包中的异常第11章异常处理5.系统定义的运行异常Exception类第11章异常处理6.系统定义的运行异常Error类系统定义的运行异常Error类中,除AWTError类是在java.awt包中外,其余的全部在java.lang包中。java.lang包中的Error类如下:第11章异常处理第11章异常处理例外的产生•自动抛出例外–运行例外–程序运行中可自动由Java解释器引发并处理的例外;编程时不需捕获或声明。–如:除0、下标越界、指针例外等–非运行例外–可在编译期由编译器确定某方法是否会发生此类例外;必须编程时捕获或声明–如:IOException,InterruptedException第11章异常处理•编程抛出例外:–在程序的相应部分抛出例外:–thrownewXXXException();–thrownewXXXException(Stringdescribe);•例:StringreadData()throwsEOFException•{………………..•thrownewEOFException(“error”);•………………….}第11章异常处理11.2Java的异常处理语句11.2.1try-catch-finally语句在大多数情况下,系统预设的异常处理方法只会输出一些简单的信息到显示器上,然后结束程序的执行。这样的处理方式在许多情况下并不能符合我们的要求,为此,Java语言为我们提供了try-catch-finally语句,使用该语句可以明确地捕捉到某种类型的异常,并按我们的要求加以适当的处理,这才是发挥异常处理机制的最佳方式。Try-catch-finally的结构如图11.3所示。第11章异常处理图11.3try-catch-finally结构执行catch执行finallytry无异常有异常第11章异常处理例外的捕获和处理•警戒区:可能会引起例外的代码段•try{•警戒区代码//引起例外•}catch(ExceptTypee){//捕获例外•例外处理代码//处理例外•}•例外处理代码(Exceptionhandlers)相当于一类特殊的方法调用第11章异常处理多个例外的处理•可用一组并列的catch块处理多例外情况–try{...}–catch(例外类1e1){...}–catch(例外类2e2){...}–...•匹配规则:–抛出对象与catch参数类型相同–抛出对象为catch参数类的子类–按先后顺序捕获(注意catch块书写时的排列顺序:先具体、后一般)第11章异常处理例外处理过程•当程序执行发生异常或遇到关键字throw时就抛出一个例外•将控制转移到相关的catch块中处理之•如果产生例外的方法本身没有相应catch语句块,则应有throws语句声明例外•退出当前方法并转向上一级调用此方法的方法的catch语句块•若始终没有catch块来处理则由运行系统处理第11章异常处理Exception类的几个方法•StringgetMessage():返回详细信息•StringtoString():返回描述,包括详细信息•voidprintStackTrace():打印出例外发生的路径,即引起例外的方法调用的序列•方法均继承自Throwable类•例:ExceptionMethods.java–抛出-捕获-处理–例外的各方法第11章异常处理异常处理•try,catch和finally语句•例6-3try{//此处为抛出具体异常的代码}catch(ExceptionType1e){//抛出ExceptionType1异常时要执行的代码}catch(ExceptionType2e){//抛出ExceptionType2异常时要执行的代码...}catch(ExceptionTypeke){//抛出ExceptionTypek异常时要执行的代码}finally{//必须执行的代码}第11章异常处理程序6-2示例•程序6-2改写了程序6-1。在程序中,捕获所发生的异常,将越界的下标重新置回0,然后让程序继续执行第11章异常处理公共异常•ArithmeticException–整数除法中,如果除数为0,则发生该类异常•NullPointerException–访问没有实例化的对象或调用它的方法inti=12/0;imageim[]=newimage[4];System.out.println(im[0].toString());第11章异常处理公共异常•NegativeArraySizeException–创建数组时,元素个数是个负数•ArrayIndexOutOfBoundsException–数组下标越界•SecurityException–一般在浏览器内抛出。–若Applet试图进行下述操作,则抛出此异常:•访问本地文件。•打开一个套接口,而不是返回到提供Applet的主机。•在运行时环境中运行另一个程序。第11章异常处理【示例程序c11_2.java】使用try-catch-finally语句自行处理异常。publicclassc11_2{publicstaticvoidmain(Stringargs[]){inta,b,c;a=67;b=0;try{intx[]=newint[-5];c=a/b;System.out.println(a+/+b+=+c);}catch(NegativeArraySizeExceptione){System.out.println(exception:+e.getMessage());e.printStackTrace();}第11章异常处理catch(ArithmeticExceptione){System.out.println(b=0:+e.getMessage());}finally{System.out.println(end);}}}运行结果如下:Exception:nulljava.lang.NegativeArraySizeExceptionAtc11_2.main(c11_2.java:11)end第11章异常处理公共异常•ArrayStoreException程序试图存取数组中错误的数据类型•FileNotFoundException试图存取一个并不存在的文件•IOException通常的I/O错误第11章异常处理异常分类•在Java中主要有三类异常。类java.lang.Throwable是使用异常处理机制可被抛出并捕获的所有异常对象的父类。它有三个基本子类,如图所示。ExceptionErrorRuntimeExceptionThrowable第11章异常处理每个类使用的目的•Error–表示很难恢复的错误,如内存越界。交给系统处理为好•RuntimeExc