您好,欢迎访问三七文档
当前位置:首页 > 高等教育 > 习题/试题 > Java程序设计――08异常处理
计算机科学与技术学院赵志崑zhaozk@sdufe.edu.cn赵志崑为什么程序需要出错处理•错误的产生是无法避免的–正常的程序运行时必然要与外界交互。–外部环境是程序无法完全控制的,有可能出现不正常的情况,如:•要访问的文件不存在,或者格式错误•脆弱的网络连接,导致数据传输中断•使用无效的数组下标–由人写出的代码中包含bug。•出现错误后,好的程序应该能做到以下几点:–通知用户发生了错误–允许用户保存当前的工作–允许用户顺利终止程序赵志崑容易出错的问题•一个好的程序应该把所有可能出错的情况都处理到。•通常,程序中出错的情况有以下几类:–环境错误:•输入错误:如用户输入错误、文件读入错误。•设备错误:如打印机卡纸。•物理限制:硬盘空间用尽,内存耗尽。–代码错误:•无效的数组下标。•使用空引用访问对象。•各自的特点:–环境错误是无法避免的,需要程序中做出特殊处理。–代码错误可以改正,但一般难以查找。赵志崑异常的概念•异常实际上是程序中错误导致中断了正常的指令流的一种事件。正常程序流程openTheFile;determineitssize;allocatememory;readthefileintomemory;closeTheFile;传统的错误处理方式openTheFile;if(theFilesOpen){determineitssize;if(gotTheFileLength){allocatememory;if(gotEnoughMemory){readthefileintomemory;if(readFailed)errorCode=-1;}elseerrorCode=-2;}elseerrorCode=-3;closeTheFile;if(closeFailed)errorCode=-4;}elseerrorCode=-5;用异常的方式来处理错误try{openTheFile;determineitssize;allocatememory;readthefileintomemory;closeTheFile;}catch(fileopenFailed){dosomething;}catch(sizeDetermineFailed){dosomething;}catch(memoryAllocateFailed){dosomething;}catch(readFailed){dosomething;}catch(fileCloseFailed){dosomething;}赵志崑异常方式的优点•传统方法将大部分精力花在出错处理上了;而异常方式则可以先写出正常流程,再添加错误处理程序。•传统方法将错误处理和正常处理流程混在一起,造成程序可读性差;而异常方式则是互相独立的,程序可读性好。•传统方法都是使用分支语句来处理错误;而异常方式则按错误类型和错误差别分组。•传统方法出错返回信息量太少,通常只有一个数字作为错误代号;而异常方式返回的是一个对象,可以传递各种信息。•传统方法只把能够想到的错误考虑到,对以外的情况无法处理;而异常方式则能够部分地处理这些情况,如异常方式中可以定义不管发生何种情况一定会执行的代码。赵志崑Java中与异常有关的语句•捕获异常:–try{…}catch(异常类异常对象){…}•向上传递异常(函数抛出异常声明):–函数定义throws异常类,异常类,…•抛出异常:–throw异常对象;赵志崑捕获异常•捕获异常使用try{}catch(){}语句。•异常在Java中实际上是一个对象。Test1.java捕获文件读写异常:try{FileReaderfin=newFileReader(Students.txt);BufferedReaderin=newBufferedReader(fin);Stringline=in.readLine();System.out.println(line);in.close();fin.close();}catch(FileNotFoundExceptione){//FileReader(“Students.txt”)产生System.out.println(e);//e.printStackTrace();}catch(IOExceptione){//in.readLine()产生System.out.println(e);}赵志崑try语句说明try语句格式:try{//接受监视的程序块}catch(异常种类异常标识符){//处理异常;}……catch(异常种类异常标识符){//处理异常;}•说明:–只要try块中的任意代码抛出一个属于catch子句所声明类的异常,那么:•跳过try块中的剩余代码;•执行相应catch子句中的异常处理代码。–如果try块中没有任何代码抛出一个异常,那么程序就会跳过所有catch子句。–如果try块中某一代码抛出一个异常,但不属于任何catch子句所声明的异常类,那么try语句所在的方法将立即退出。–catch子句能够捕获子类型的异常。将Test1.java中两个catch语句调换顺序。–catch子句不能捕获已经处理过的异常。赵志崑异常的处理原则•如何知道代码中会产生哪些异常–对于代码中没有处理的异常,编译时会报错。–查看帮助文档,使用一个方法时,查看方法声明中的throws部分。•处理异常的原则–捕获那些知道如何处理的异常。–向上级调用者传递那些不知道该如何处理的异常。•如何向上级调用者传递异常–不使用catch子句捕获这些异常。–在方法声明时使用throws关键字向上传递这些异常。–在方法外部(从方法调用者的角度)看来,就相当于调用此方法的语句会产生这些类型的异常。赵志崑向上传递异常•当一个方法自己无法处理可能产生的异常时,可以将异常传递给方法的调用者。•上传异常,在方法声明时添加throws说明。publicstaticvoidmain(String[]args){try{read();}catch(IOExceptione){System.out.println(e);}}main方法中调用了read()方法,可能产生IOException,所以必须处理。或者自己处理,或者继续上传。Test2.javastaticvoidread()throwsIOException{FileReaderfin=newFileReader(Students.txt);BufferedReaderin=newBufferedReader(fin);Stringline=in.readLine();System.out.println(line);in.close();fin.close();}FileReader和in.readLine都可能产生IOException,但在read()方法中不知道如何处理,所以只能传递给read方法的调用者(使用者)。赵志崑逐级传递异常•方法可以将异常向上传递给调用者,所以可以逐级上传。最后上传到main函数,再传递给Java虚拟机。虚拟机可以最终处理所有异常。•异常在传递过程中,一旦遇到相应的catch语句,则被捕获处理并停止传递,所以异常情况可以在适当的位置被处理。•异常只有捕获或者传递两种处理方法,二者必居其一,所以保证了所有的异常都被处理。Java虚拟机mainmethod1method2catchexceptionexceptionexceptionexceptionexception赵志崑抛出异常•当方法执行中检测到非正常情况,而在方法内部又处理不了时,就需要抛出异常。抛出异常实际上等于先产生出一个异常,然后将异常传递给调用者。•抛出异常使用throw语句,分为三步:–找到一个合适的异常类–创建该类的一个对象–抛出该对象(转去执行异常处理程序)Stringread(StringaFileName,intaCount)throwsEOFException{……if(aCountin.available()){thrownewEOFException(没有这么多字符。);}……}Test3.javapublicstaticvoidmain(String[]args){try{read(Test3.txt,20);}catch(EOFExceptione){System.out.println(e);}}赵志崑捕获并抛出异常•方法中能够部分处理异常时,需要先捕获异常,然后进行自己的处理,最后再将异常传递给调用者。staticvoidread()throwsIOException{try{FileReaderfin=newFileReader(Students.txt);BufferedReaderin=newBufferedReader(fin);Stringline=in.readLine();System.out.println(line);in.close();fin.close();}catch(IOExceptione){System.out.println(read:+e);throwe;}}Test4.javapublicstaticvoidmain(String[]args){try{read();}catch(IOExceptione){System.out.println(main:+e);}}赵志崑异常的种类•简化的Java异常类继承关系图。ThrowableErrorExceptionIOExceptionRuntimeException赵志崑异常种类简介•任何异常类都派生自Throwable类。Throwable立即分为两个分支:Error和Exception。–Error用于描述运行时系统的内部错误和资源耗尽错误。这种错误发生时,除了通知用户并终止程序外没有别的办法,所以不应该抛出这种类型的错误。–Exception又分为两个分支:IOException和RuntimeException。•产生RuntimeException的原因是编程错误,应该修改程序进行改正。如:–错误的造型转换–越界数组访问–空引用访问–被0除•产生IOException的原因是正确的程序遇到了意外的情况,必须进行处理。如:–打开不存在的文件–打开错误的URL•Exception分支是编写程序时处理的重点。赵志崑各类异常的处理•各类异常的处理方法。ThrowableErrorExceptionIOExceptionRuntimeException不做处理因为没有能力处理必须捕获或传递可以抛出可以捕获自己处理可以不做处理由虚拟机处理因为需要修改程序消除异常赵志崑自定义异常•当标准的异常类不足以描述出现的异常情况时,可以自己创建异常类。自定义异常一样需要捕获或传递。–创建异常类只需从Exception或其子类派生一个子类即可。–该类一般具有一个无参数构造器和一个带字符串参数构造器。publicvoidselect(intaCount)throwsSelectingException{if(aCounttotalCount){thrownewSelectingException(“无法从选出”+aCount+“名同学。);}}Test5.javaclassSelectingExceptionextendsIOException{publicSelectingException(){};publicSelectingException(Stringmsg){super(msg);}}赵志崑finally块•try语句可以带有finally块,表示一定执行的程序块,不管发生不发生异常,也不管发生何种类型的异常。Test7.javaFileReaderfin=null;BufferedReaderin=null;try{fin=newFileReader(Students.txt);in=newBufferedReader(fin);Stringline=in.readLine();Syste
本文标题:Java程序设计――08异常处理
链接地址:https://www.777doc.com/doc-3805517 .html