Java基础第7章异常处理

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

1第七章异常处理为了构建健壮、灵活的代码,异常就是程序员必须要面对的问题。异常处理也因此成为了衡量代码优劣的重要尺度。当程序产生异常,能够启用相应的异常处理程序进行异常处理,使得程序能够继续运行下去。本章学习目标:了解异常的基本常识熟悉异常处理的基本原则掌握如何创建和使用自定义异常处理程序7.1异常的基本概念发现错误的最佳时机是在编译阶段,也能使系统的维护代价降到最低。但是,编译期间不可能找出所有的错误,原因就在于:对于JAVA语言来说,编译过程的本身除了把源程序编译成JAVA虚拟机能够执行的.class字解码文件外,仅仅对程序进行语法性验证。剩下的问题就必须在运行期间去解决。这就需要通过某种方式,把错误源的相关信息传递给某个错误处理者。JAVA异常处理机制也因此而诞生了。19781108gxy4205891067.1.1什么是异常在程序运行时,打断正常程序流程的任何不正常的情况称为错误或异常。“异常处理”的实现,最早可以追溯到20世纪60年代的操作系统。经过几十年的积累,才使得“异常处理”被正式的纳入语言的范畴。一个“注重实效的程序员”是不应该回避异常处理的。但是很可惜,或许异常处理真的很困难吧。大家都有意、无意的回避了其中的一些异常。这是很不负责任的做法。7.1.2JAVA标准异常JAVA中的Throwable类是所有异常类的顶级父类,并且有两个直接子类。一个是Error类,另一个是Exception类。这两个子类代表JAVA异常的两种类型。Error用来表示编译时和系统错误,Exception是与编程有关的所有类的父类,是可以被抛出异常的基本类型。而JAVA程序员所关心也就是Exception类型的异常。如果您看过SUN官方的JAVA文档会发现:其实所有的异常类,除了类名不同外,其它的内容都极其的相似。所以要想写出优雅的异常处理程序,关键是要理解JAVA异常概念以及如何在恰当的时间应用它。27.1.3JAVA异常处理机制JAVA程序的执行过程中如果出现异常,就会有几件事随之发生。首先,自动生成一个异常类的对象,该对象包含了有关异常的基本信息,然后当前执行路径被终止,并且从当前环境中弹出异常对象的引用(其实这个异常对象的引用是被自动提交给JAVA运行时系统的),这个过程称为“抛出异常”。当JAVA运行时系统接收到异常对象时,会寻找能处理这一异常的代码,并把当前异常对象交给其处理,这个过程称为“异常捕获”。7.2捕获异常首先让我们先看一个简单的示例。例7.1:publicclassfirstException{publicstaticvoidmain(Stringargs[]){inttemp1=20;inttemp2=0;System.out.println(temp1/temp2);System.out.println(上面因为除数为零,所以应该对异常进行处理,否则本行将不能输出);}}编译:javacfirstException.java运行:javafirstException这时程序就终止了,并抛出一个JAVA运行时捕获的异常,内容如下:Exceptioninthreadmainjava.lang.ArithmeticException:/byzeroatfirstException.main(firstException.java:7)这段提示的意思是:在main线程中产生了一个java.lang.ArithmeticException异常:原因是除数为0,错误代码在firstException.java这个文件的第7行。(线程的概念将在后面的章节进行讲解。)。下面我们对程序进行一下修改并保存,使之能够正常运行。例7.2:publicclassfirstException{publicstaticvoidmain(Stringargs[]){inttemp1=20;inttemp2=0;try{System.out.println(temp1/temp2);3}catch(ArithmeticExceptione){System.err.println(我是一个异常);}System.out.println(上面因为除数为零,所以应该对异常进行处理,否则本行将不能输出);}}编译:javacfirstException.java运行:javafirstException结果:我是一个异常上面因为除数为零,所以应该对异常进行处理,否则本行将不能输出虽然负数开平方绝对是不可以的,但是JAVA运行时系统却不会捕获该异常,只是把开平方的结果赋予NaN值。这个NaN是“NotaNumber”,即非数值(也有称其为“不确定式”的,但是非数值可能更合适一些)。但是比较有意思的是JAVA本身对NaN本身的定义,如下:publicstaticfinaldoubleNaN;因为对NaN的讨论已经超出本书的范围,所以在此不进行详细讨论,但是读者应该知道的是:即便两个NaN值也是不相等的。下面这个例子就能很好的说明这个问题:例7.3:publicclasstemp{doublea=-10;a=Math.sqrt(a);System.out.println(a);System.out.println(a==a);doubleb=Double.NaN;System.out.println(b);System.out.println(b==b);}编译:javactemp.java运行:javatemp结果:NaNFalseNaNFalse从firstException.java这个例子不难看出,异常捕获是在try{}块中进行的。try{}块中是可能产生异常的代码,这段代码在JAVA中称为监控区(guardedregion)。而异常处理是在catch(){}中进行的。4对于异常处理程序来说,一个try{}块对应着一个或多个catch(){}块,和一个在语法上可有可无的finally{}块。但是程序一旦包含了finally{}块,则不管是否发生异常,finally{}块里的语句是一定要执行的。乍看上去有一点像现实中的“霸王条款”。但正是这个貌似“霸王条款”的finally{}块,它对于引入了“垃圾回收”机制的JAVA来说,有着极其特殊的价值。因为“垃圾回收”是由JVM控制的,我们不知道也不可能控制回收的时间。对于像已经使用完或无效的数据库连接这样占用系统大量宝贵资源的“垃圾”来说,必须要在第一时间将其释放。这时候JVM的“垃圾回收”机制的处理能力就显得有些苍白,在Web应用上更是如此。这时如果程序中加上了一个finally{}块,并且在里面加上一行释放连接的代码,问题就很简单的解决了。下面的这个小程序能有助于读者对异常处理的理解。程序功能描述:定义一个可以实现统计前N名学生的平均成绩的方法。要求方法能接受学生成绩表和计算平均成绩的学生个数这两个参数。其中成绩表为整型数组,学生人数为普通的整型变量,实现如下:例7.4:publicclassexampleException{publicstaticvoidmain(Stringargs[]){intgrades[]=newint[]{95,80,65,78,58};//计算前10名学生的成绩。countAverage(grades,10);}publicstaticdoublecountAverage(intgrades[],inttotal){intsum=0;doubleave=0.0;booleanjudge=false;try{for(inti=0;itotal;i++){sum+=grades[i];}ave=(double)sum/total;}catch(ArithmeticExceptione){//其他的处理代码System.err.println(total为零,不能计算);judge=true;}5catch(ArrayIndexOutOfBoundsExceptione){//其他的处理代码System.err.println(统计的学生个数超出成绩表中的学生总人数);judge=true;}finally{//其他的处理代码System.err.println(不管程序是否有异常,我都将会输出);if(judge==true){System.err.println(因为参数有误,将返回0.0);return0.0;}elsereturnave;}}}保存为exampleException.java编译:javacexampleException.java运行:javaexampleException程序结果为:统计的学生个数超出成绩表中的学生总人数不管程序是否有异常,我都将会输出因为参数有误,将返回0.0读者可以试着把return语句放到try{}块中或者catch(){}块中,然后把finally{}块中的关于返回值的语句去掉。看看程序能否通过编译并且正常运行。7.3创建自定义异常房地产开发商根据市场部调查来的结果,最终抽象出适合某一类型用户群的商品房模型。经过施工使模型成为现房。而有该类型需求的用户,在购买完商品房后,不可避免的要对其进行装修:该掏壁橱的地方掏壁橱、该铺地毯的地方铺地毯……,最终设计出一套适合自己的住房。这样做的原因很简单。从开发商的角度来讲:他只能根据用户群的需求,建一个比较符合用户要求的“筒子楼”。而不可能为每一个用户量身定做住房(当然如果付得起费用的话,这也有可能)。这其中最主要的原因是:开发商在时间上耗不起。从用户的角度来讲:一屋子的水泥墙,连个床都没有。所以装修也就避不可少了。与现实中的房地产开发商比起来,SUN为JAVA异常这群“用户”定制的“JDK6筒子楼”要高明得多:里面有“床”、有“空调”、有“有电视”……。但是不管怎样,它依然是“筒子楼”,所以就不可避免的满足不了我们所有的要求。另外有些功能也不是我们所希望的那样。基于这点,创建自定义异常就势在必行。但是读者需要知道的是:我们是在为“JDK筒子楼”装修,而非重建。所以我们要“extendsException”。另外,在为“JDK筒子楼”装修前,还是看看都提供了那些主要功能吧。Java.lang软件包中的异常ExceptionClassNotFoundExceptionClassNotSupportedExceptionIllegalAccessExceptionInstantiationExceptionInterruptedExceptionNoSuchMethodExceptionRuntimeExceptionArithmeticExceptionArrayStoreExceptionIllegalArgumentExceptionIllegalThreadStateExceptionNumberFormatExceptionIllegalMonitorStateExceptionIndexOutOfBoundsExceptionArrayIndexOutOfBoundsExceptionStringIndexOutOfBoundsExceptionNegativeArraySizeExceptionNullpointerExceptionSecurityException上面所列出的java.lang包中提供的这些异常基本能够满足初学者的使用需求。其余包中的异常请参照相关资料。如果书中的示例程序需要用到其它包中的异常,将给出特别的说明和解释。另外读者需要知道的是:异常的类库也在不断的扩大中,而且在第三方的异常库中依然可能存在其他的异常。在使用的时候如果出现了奇怪的异常,则应该特别注意了。Java的JDK中所提供的异常类数以百计。程序员不可能也没有必要将它们全部记住,用的时候可以去查手册,里面有非常详细的信息。而如果仅仅是要找到一个合适的异常类却有一个很简单也很巧妙的办法:把可能产生该类异常的代码放到一个main()方法中,并且把代码设置成一定会抛出异常的状

1 / 18
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功