第4章异常北京大学计算机系代亚非2第4章异常4.1异常的概念4.2异常的分类4.3捕获异常4.4声明异常4.5抛出异常4.6创造自己的异常4.7总结34.1异常的概念什么是异常?异常实际上是程序中错误导致中断了正常的指令流的一种事件.没有处理错误的程序:read-file{openTheFile;determineitssize;allocatethatmuchmemory;closeTheFile;}44.1异常的概念以常规方法处理错误openFiles;if(theFilesOpen){determinethelenthofthefile;if(gotTheFileLength){allocatethatmuchmemory;if(gotEnoughMemory){readthefileintomemory;if(readFailed)errorCode=-1;elseerrorCode=-2;}elseerrorCode=-3;}elseerrorCode=-4;}elseerrorCode=-5;54.1异常的概念观察前面的程序你会发现大部分精力花在出错处理上了.只把能够想到的错误考虑到,对以外的情况无法处理程序可读性差出错返回信息量太少64.1异常的概念用异常的形式处理错误read-File;{try{openTheFile;determineitssize;allocatethatmuchmemory;closeTheFile;}catch(fileopenFailed){dosomething;}catch(sizeDetermineFailed){dosomething;}catch(memoryAllocateFailed){dosomething;}catch(readFailed){dosomething;}catch(fileCloseFailed){dosomething;}}74.1异常的概念和传统的方法比较异常的优点:1.把错误代码从常规代码中分离出来2.把错误传播给调用堆栈3.按错误类型和错误差别分组4.系统提供了对于一些无法预测的错误的捕获和处理5.克服了传统方法的错误信息有限的问题method1method2method3method4产生异常传递处理异常84.1异常的概念.classExcepTest{publicvoidmain(Stringargs[]){intb=0;inta;try{a=4/b;}catch(ArithmeticExceptione){System.out.println(“dividedby0”);}}}try{URLurl=newURL(”,”hit.gif”);}catch(MalformedURLEceptione){badURL=true;repaint();}94.2异常的分类异常是一个对象,它继承自Throwable类,所有的Throwable类的子孙类所产生的对象都是例外.Error:由Java虚拟机生成并抛出,Java程序不做处理.RuntimeException(被0除等系统错误,数组下标超范围):由系统检测,用户的Java程序可不做处理,系统将它们交给缺省的异常处理程序.Exception(程序中的问题,可预知的):Java编译器要求Java程序必须捕获或声明所有的非运行时异常throw:用户自己产生异常104.2异常的分类.ThrowableErrorExceptionRuntimeException缺省的异常处理程序由用户捕获或声明并处理不做处理用户自己产生的异常要处理114.3捕获异常捕获并处理异常try{//接受监视的程序块,在此区域内发生//的异常,由catch中指定的程序处理;}catch(要处理的异常种类和标识符){//处理异常;}catch(要处理的异常种类和标识符){//处理异常;}124.3捕获异常常见的异常ArithmeticExceptionArrayIndexOutOfBandsExceptionArrayStoreExceptionIOExceptionFileNotFoundExceptionNullPointerExceptionMalformedURLExceptionNumberFormatExceptionOutOfMemoryException如果在使用能够产生异常的方法而没有捕获和处理,将不能通过编译134.3捕获异常例:编写Java程序,包含三种异常算术异常,字符串越界,数组越界观察输出信息:每个异常对象可以直接给出信息144.3捕获异常classfirst_exception{publicstaticvoidmain(Stringargs[]){charc;inta,b=0;int[]array=newint[7];Strings=Hello;try{a=1/b;}catch(ArithmeticExceptionae){System.out.println(“Catch“+ae));}try{array[8]=0;}catch(ArrayIndexOutOfBoundsExceptionai){System.out.println((“Catch“+ai);}try{c=s.charAt(8));}catch(StringIndexOutOfBoundsExceptionse){System.out.println((“Catch“+se);}}}154.3捕获异常一定会执行的程序块---finally异常处理的统一出口try{//常规的代码;}catch(){//处理异常}finally{//不论发生什么异常(或者不发生任何异常),都要执行的部分;}164.3捕获异常finally在文件处理时非常有用try{对文件进行处理的程序;}catch(IOExceptione){//对文件异常进行处理;}finally{不论是否发生异常,都关闭文件;}174.4声明异常一个方法不处理它产生的异常,而是沿着调用层次向上传递,由调用它的方法来处理这些异常,叫声明异常.声明异常的方法在产生异常的方法名后面加上要抛出(throws)的异常的列表voidcompute(intx)throwsArithmeticException{…}returnTypemethodName([parameterlist])throwsexceptionList184.4声明异常例:若因某种原因不想在创建URL的方法中处理异常publicmethod1(){intx;try{x=System.in.read();compute(x);}catch(IOExceptionioe){System.out.println(“readerror”);}catch(ArithmeticExceptione){System.out.println(“devidedby0”);}}publicintcompute(intx)throwsArithmeticExceptione){returnz=100/x;}194.4声明异常method1computer异常抛出处理204.4声明异常例:说出程序执行结果publicclassexception1{voidProc(intsel)throwsArithmeticException,ArrayIndexOutOfBoundsException{System.out.println(“InSituation+sel);if(sel==0){System.out.println(noExceptioncaught);return;}elseif(sel==1){intiArray[]=newint[4];iArray[10]=3;}}214.4声明异常publicstaticvoidmain(Stringargs[]){try{Proc(0);Proc(1);}catch(ArrayIndexOutOfBoundsExceptione){System.out.println(Catch+e);}}c:jviewthrowsExceptionInSituation0noExceptioncaughtInSituation1Catchjava.lang.ArrayIndexOutOfBoundsException:10224.5抛出异常抛弃异常:不是出错产生,而是人为地抛出throwThrowableObject;thrownewArithmeticException();例:编写程序人为抛出(JavaThrow.prj)ArithmeticException,ArrayIndexOutOfBoundsExceptionStringIndexOutOfBoundsExceptionAmethodExceptionAnothermethodthrowcaught234.5抛出异常classJavaThrow{publicstaticvoidmain(Stringargs[]){try{thrownewArithmeticException();}catch(ArithmeticExceptionae){System.out.println(ae);}try{thrownewArrayIndexOutOfBoundsException();}catch(ArrayIndexOutOfBoundsExceptionai){System.out.println(ai);}try{thrownewStringIndexOutOfBoundsException();}catch(StringIndexOutOfBoundsExceptionsi){{System.out.println(si);}244.6创造自己的异常不是由Java系统监测到的异常(下标越界,被0-除等),而是由用户自己定义的异常.用户定义的异常同样要用try--catch捕获,但必须由用户自己抛出thrownewMyException.异常是一个类,用户定义的异常必须继承自Throwable或Exception类,建议用Exception类.254.6创造自己的异常形如:classMyExceptionextendsException{….};例1:计算两个数之和,当任意一个数超出范围时,抛出自己的异常publicclassNumberRangeExceptionextendsException{publicNumberRangeException(Stringmsg){super(msg);}}264.6创造自己的异常.publicbooleanaction(Eventevt,Objectarg){try{intanswer=CalcAnswer();answerStr=String.valueOf(answer);}catch(NumberRangeExceptione){answerStr=e.getMessage();}repaint();returntrue;}274.6创造自己的异常.publicintCalcAnswer()throwsNumberRangeException{intint1,int2;intanswer=-1;Stringstr1=textField1.getText();Stringstr2=textField2.getText();try{int1=Integer.parseInt(str1);int2=Integer.parseInt(str2);if((int110)||(int120)||(int210)||(int220)){NumberRangeExceptione=newNumberRangeExce