您好,欢迎访问三七文档
当前位置:首页 > 电子/通信 > 综合/其它 > 39第07章 JAVA语言中的异常
第07章JAVA语言中的异常主讲:程细柱韶关学院计算机科学学院JAVA语言中的异常编写程序时多多少少总会有些错误,程序中的语法错误会在编译时被发现并修正,而有些错误是发生在运行阶段的。这些错误依照其严重程度分为两类:一类是致命性的严重错误,它们的出现可能会导致系统崩溃,并且程序员并不能编写程序解决所出现的问题。另一类是普通级别的错误,这类错误如果不加控制就使程序非正常中断,但如果编写代码来处理的话,就有可能避免中断程序的执行。这类错误一般地称为异常(Exception),用来处理异常的过程称为异常处理。JAVA语言中的异常在Java中主要有三类异常。事实上,Java定义了类java.lang.Throwable,它是使用异常处理机制可被抛出并捕获的所有异常对象的父类。它有三个基本子类,如下图:JAVA语言中的异常每个类的使用目的不同:Error表示很难恢复的错误。一般不期望用户程序来处理,即使程序员有能力处理这种错误,也还是交给系统处理为好。RuntimeException用来表示设计或实现方面的问题。因为设计和实现正确的程序不会引发这类异常,所以常常不处理它。发生这类异常时,运行时环境会输出一条信息,提示用户修正错误。其他异常表示运行时因环境的影响可能发生并可被处理的问题。因为用户的错误很可能导致这类问题发生,我们要学习的是如何处理这类异常。7.1异常示例例7-1文件操作功能描述{openTheFile;//打开文件determineitssize;//获取文件的长度allocatethatmuchmemory;//分配内存read-file;//读文件closeTheFile;//关闭文件}7.1异常示例(续)实现文件读取的程序大多有上述这样的程序框架。因为文件存放在外存,程序要访问文件时必须先要将文件放入内存然后才能访问。这段程序是顺序执行结构,而前一句执行的结果又直接影响后一句是否能执行。如果中间哪一条语句执行不正确,后续语句都不能正确执行,程序也会中断。所以凡是有输入输出操作的语句都可能会出现问题。7.1异常示例(续)例7-2增加了约束的文件操作功能描述openFiles;//打开文件if(theFilesOpen){//判定打开是否正确determinethelengthofthefile;//获取文件的长度if(gotTheFileLength){//判定已得到文件长度allocatethatmuchmemory;//分配内存if(gotEnoughMemory){//内存分配成功readthefileintomemory;//读文件if(readFailed)errorCode=-1;//读取失败elseerrorCode=-2;//读取成功closeTheFile;//关闭文件}else7.1异常示例(续)elseerrorCode=-3;//内存分配不成功}elseerrorCode=-4;//没有得到文件长度}elseerrorCode=-5;//文件打开不正确Java提供的异常处理机制程序发生异常时称为产生了一个异常事件,系统根据异常生成一个异常对象。根据这个异常的种类,该对象可能由正在运行的方法生成,也可能由JVM生成。异常对象中包含了该异常必要的详细说明信息,包括所发生的异常事件的类型及异常发生时程序的运行状态。生成的异常对象传递给Java运行时系统,运行时系统寻找相应的代码来处理这一异常。我们把生成异常对象并把它提交给运行时系统的这一过程称为抛出(throw)一个异常。7.1异常示例(续)异常发生后,Java运行时系统从生成对象的代码块开始进行回溯,沿方法的调用栈逐层回溯寻找处理代码,并把异常对象交给该方法处理,这一过程称为捕获(catch)。如图所示:7.1异常示例(续)例7-3下面用异常处理方式重写例7-2。try{openTheFile;//打开文件determineitssize;//获取文件的长度allocatethatmuchmemory;//分配内存read-File;//读文件closeTheFile;//关闭文件}catch(fileopenFailed){//文件打开失败的处理代码;}catch(sizeDetermineFailed){//不能获得文件大小的处理代码;}catch(memoryAllocateFailed){//内存分配失败的处理代码;}catch(readFailed){//读文件失败的处理代码;}catch(fileCloseFailed){//关闭文件失败的处理代码;}finally{//需要统一处理的代码;}程序7-1I/O操作示例importjava.io.*;publicclassTryException{publicstaticvoidmain(String[]args){TryExceptiont=newTryException();//创建实例t.go();//调用方法}publicvoidgo(){try{InputStreamReaderisr=newInputStreamReader(System.in);//输入流BufferedReaderbr=newBufferedReader(isr);br.readLine();//I/O操作,按任意键}catch(Exceptione){//读过程中发生异常的处理/*异常处理代码,目前为空,表明发生异常时不做任何处理*/}//EndoftrySystem.out.println(Continuing);}}异常类和错误类Java语言在所有的预设包中都定义了异常类Exception和错误类Error。Exception类是所有异常的父类,Error类是所有错误的父类,这两个类同时又是Throwable的子类。它们的层次结构如图所示:异常示例程序7-2再次编写打印程序。publicclassHelloWorldApp{publicstaticvoidmain(String[]args){inti=0;Stringgreetings[]={Helloworld!,No,Imenait!,HELLOWORLD!!};while(i4){System.out.println(greetings[i]);i++;}}}7.2异常处理虽然引发某个具体异常的语句可能是一条,但相关的语句可能会有多条,程序中使用try语句将这些语句全部括住。在try语句后面是一组catch语句,对所括住的语句可能引发的异常进行分类,对每一种类型的异常提供一段相应的处理代码,每种异常对应一个catch语句。7.2.1异常处理语句:try与catchtry与catch语句的语法格式如下:try{//此处为抛出具体异常的代码}catch(ExceptionType1e){//抛出ExceptionType1异常时要执行的代码}catch(ExceptionType2e){//抛出ExceptionType2异常时要执行的代码...}catch(ExceptionTypeke){//抛出ExceptionTypek异常时要执行的代码}finally{//必须执行的代码}其中,ExceptionType1,ExceptionType2,…,ExceptionTypek是产生的异常类型。根据发生异常所属的类,找到对应的catch语句,然后执行后面的语句序列。Finally语句异常处理中有一个特殊的语句,即finally语句。它是最后一条语句,Java规定,不论是否捕获到异常,总要执行finally后面的语句。即使try块中包含return、break、continue、throw等语句,finally语句也会被执行。finally语句不执行的情况只有一种,即在保护代码内执行了System.exit()方法后,将不再执行finally后面的语句,这是不执行finally后面语句的惟一一种可能。公共处理示例例7-4公共处理示例try{openfile();//打开文件read_file();//读文件}finally{closefile();//关闭文件}因为closefile()方法放到了finally块中,所以总被执行。公共处理示例再看下面的例子。程序7-3总会输出“finally”,而“aftertry”仅在aVar的值不等于10时才被输出。程序7-3公共处理的完整代码publicclasstryAgain{publicstaticvoidmain(Stringargs[]){intaVar=0;try{if(aVar==10){return;}}finally{System.out.println(finally);}System.out.println(aftertry);}}程序7-4再次改写打印程序7-2publicclassHelloWorld{publicstaticvoidmain(String[]args){inti=0;Stringgreetings[]={Helloworld!,No,Imenait!,HELLOWORLD!!};while(i4){try{System.out.println(greetings[i]);}catch(ArrayIndexOutOfBoundsExceptione){System.out.println(重置下标值);i=-1;}catch(Exceptione){System.out.println(e.toString());}finally{System.out.println(Thisisalwaysprinted);}i++;}}}异常处理示例//p131程序将无限执行,进入死循环。7.2.2公共异常(1)ArithmeticException异常。进行表达式计算时,除数不能为零。当程序中出现除数为零,或在整数运算中对零取模时,就会发生该类异常。如下面表达式将引发ArithmeticException异常:inti=12/0;//除数为0floatavar=12%0;//对0取模7.2.2公共异常(续)(2)ArrayIndexOutOfBoundsException异常。这是数组下标越界异常。数组元素的个数在数组初始化时已经确定下来,程序中访问数组元素时,不能超过数组的长度。系统根据length值来检查数组下标表达式,如果超出这个值,则将导致该异常。见下例。例7-5数组下标越界classArrayOut{publicstaticvoidmain(Stringargs[]){intaArray[]=newint[3];aArray[3]=0;//数组下标只能是0、1、2}}7.2.2公共异常(续)(3)IncompatibleClassChangeException异常。这是类不兼容异常。当修改一个类的定义后,引用该类的其它类没有重新编译,就会产生该异常。对应的情况有以下两类:·一个类中的变量声明由静态变成非静态,或由非静态变成静态,而其它访问该类这一变量的类没有被重新编译。·类中声明的某个域或是某个方法被删除,而其它访问该域或该方法的类没有被重新编译。(4)IncompatibleTypeException异常。这是类型不兼容异常。名字虽然与前一个异常很类似,但含义不相同。如果试图定义一个接口的实例,则会引发IncompatibleTypeException异常。7.2.2公共异常(续)(5)NegativeArraySizeException异常。这是数组元素个数为负异常。数组长度应该是一个大于等于0的整数,所以定义数组时,方括号中的数不能写负数。当然,如果定义一个元素个数为零的数组是没有使用价值的,所以也应该避免。创建数组时,如果指定的元素个数是个负数,则会引发该异常。例7-6引发数组元素个数为负异常示例classNegArray{publicstat
本文标题:39第07章 JAVA语言中的异常
链接地址:https://www.777doc.com/doc-5726771 .html