JAVA程序员.doc

所需积分/C币:10 2011-09-20 07:54:38 383KB PDF

Java异常机制.pdf Java异常机制.pdf Java异常机制.pdf
Throwable Error Exception RuntimeException IOEXception checked Exception 1) Throwable所有异常和错误的相关父类 2)有两个直接子类分别是Eror和 Exception - Error是指不可恢复的严重问题,不要试图捕获将直接退出程序 EXception是程序设计时设计不合理代码错误Java认为可以恢复 Checked已检查的Java提供的检查的其他语言没有提供 checked异常Java 认为 checked异常都是可以处理[可以恢复]的异常,必须处理.如果不处理,编译的 时候会报错〔但是大多数异常无法处理只能抛出这样降低开发效率使Java被诟病) Runtime Exception运行时不检查 Runtime Exception是那些可能在Java 虚拟机正常运行期间抛岀的异常的超类。可能在执行方法期间拋岀但未被捕获的 Runtime Exception的任何子类都无需在 throws子旬中进行声明。>尽量使 用,因为更加灵活,无需显式声明 4. finally关键字 在刚刚的例子的 catch后加入如下代码 f⊥na11 y System.out, print1n("我关流,你莫管") try i fis. close( t catch (TOExcepti cn e)i e printstackTrace()i 输出 我出现是因为Fi1e没有 found java.io. EileNotFourdException:D:κ iaoriben.jpeg(系统找不到指定的文件。) at java. io, FileInputStream open(Native Method) at java. io FileInputstream. <init>(Unknown Source) at java.io. FileInputstream. < init>(Unknowr Source) at org. ss. ExceptionControl main(ExcepticnContro. java: 11) 我关流,你莫管 Exception in thread "main"java.lang. NullPcinterExceptior at org. ss. ExceptionControl main(Exception Control. java: 23) 可以看到,异常抛出时fnay也是被执行的。在fnly中常关闭连接,流(JDBC) 等资源 注意点 otry{ System. exit(0)}阻止 finally块执行 tryfreturn 不会阻止fna!y执行 o手工抛异常对象 throw new Exception("是否执行 finally");不会阻止 nal 5.继承中的异常问题 package org. Ssi import java.io FileInputstream; ±mp。 t java.io.Fi1 eNotFoundException; import java. 10. TOExceptioni lass Father i public void aMeh tod()throws IOException i ileInputstream fis=new FileInputstream("C: dd. txt")i class Bigone extends Father Public void aMehtod( throws FileNotFoundException class BigTwo extends Father Public void aMehtod( throws Exception class BigThree extends Father public void aMehtod( i 如果存在继承关系: 父类方法声明抛出异常对象 子类 -1:不声明抛出 2:声明相同异常信息 3父类方法,声明父类异常,子类声明子类异常 (如果方法体内写了 super. aMothedO,就必须抛出 IOEXception) 6.自定义异常 1)一般开发一个项目需要自定义至少—个项目异常类以统一管理、处理异常 2)什么时候自定义抛出异常 如果程序的数据执行与既定业务不符,那这就是异常这种异常系统不能够理解, 需要程序员来自行决定是否抛出 -不可恢复的"底层"错误 3)自定义异常构造器的一般写法:四个构造方法 public class ApplicationException extends RuntimeExceoticr public ApplicationException()I super ( public ApplicationException(string message)[ super(message)i public ApplicationException (Throwable cause)i super(cause); public AppLicationException(String message, Throwable cause)t super(message, cause)i 4)统一包装的方法 mpoT七 1o. FileInputstream import java. io. FileNotFoundException public class UserServicef public static boolean login() FileInputstream fin nu11; fin- new FileInputstream("a tx=")i ] catch(FileNotFoundException e)[ /统·包装,将抛出的异常捕获再将异常包装后抛出以供外层获 throw new ApplicaticnException(e)i return七rue; 7.异常处理规贝 o不要过度使用异常会减慢程序运行速度 o不要用异常代替流程控制:代价高昂 o不要将过大的内容包括在ty块中 o不要忽略捕到的异常:至少 printStackTrace0 Catch( Exception)( //do nothing. nothing happened 深入部分: 是否使用异常使用时间频度来确定异常情况 1)当Java程序违反了Java的语义的时候,Java虚拟机会将发生的错误表示为 个异常。所谓违反语义包含两种情況。一种是Java类库内置的语义检查。例如数 组下标越界,会引发 ndexOutOfBoundsException;i问nu的对象,会引发 NullPointerException。另一种情况是Java允许程序员扩展这种语义检查,也就是 自定义异常,并自由选择在何时用 throw关键字引发异常。 2)任何异常都会引起程序控制流的转移,当异常被拋岀后,Java虚拟机会在抛 出异常的方法中寻找最经的匹配的 catch语句,如果没有则在调用方法中找,直至 遍历调用栈中所有方法位置。如果没有找到任何匹配的 catch语句,则会调用 Thread Group. uncaught Exception0方法 3)异常对性能的影响表现在两个方面。一方面是异常的创建,捕获和处理都需要 很高的代价。这同虚拟机处理异常的方式有关。在Java内存模型中,有一个称为栈 stack)的内存区域,每次方法调用都会在生成一帧( frame)来存储方法的相关 信息,包括局部变量,参数,返回值和代码信息等。 当 method4()中抛出异常时,Java虚拟机会首先根据帧中的信息执行fna!语 句块,然后在 method40的帧寻找匹配的 catch。如果没有找到,则将 method40 帧 从栈中弹AMhd4()的帧 帧_ method30 帧 nethod 帧 ethods 帧 nano 帧 ThreadGroup. uncaughLExcepliono 的帧从栈中弹出,然后在调用 method4的方法 method3中进行匹配,如此反复 地在栈中想下匹配,直至达到 Thread group. uncaught Exception(为止。整个过程比正常 的流程需要付岀更多的代价。因此用异常进行流程控制,在性能上不可以被接受的 另一方面,即使异常没有发生,包含异常处理的仍然需要较多的运行时间,尤其是 在包含了 finally块时。 考虑两段代码 NormalTest. java ExceptionalTest. java 两者在功能上完全一致,但是执行时间却有很大区别。在 windows和 Solaris两种 系统上,使用JDK14测试的结果见下表 运行时间 windows Solaris 无异常处理代码 2714 4090 包含异常处理的代码 5548 7789 比率 0.49 0.53 结果就不言而喻。 Java异常机制的设计目的是提供一种可扩展的语义检查机制。然而对大多数程序员 来说,语义检查是种虚无缥缈的概念。何时使用异常呢?在异常的时侯使用异常, 什么情况属于异常的情况呢?一个简单的的原则就是考虑时间频度。对于方法 method(),如果 method()的一个流程分支经常发生,甚至在常用的调用中每 一次都会发生,那么就不是异常控制的合适的对象了。原因很简单:从性能是不能 接受的,另一方面从逻辑上讲,经常发生的情况。显然不能作为异常来处理。 Java类库为如何确定异常情况给出了极好的例子。观察一下代码 1e工 nputstream fin; fin = new F-letnputstream("fileName " t catch (FileNotFoundException e)( System. out.prin=ln('Can't finc file: fileName") xe七uxn FileInputStream的read0方法通过返回-1来表示到达了文件尾。虽然 reado方法 也会抛出 IOEXception但并不是用来表示文件末尾而是表示一般的输入输出错误. 这样的设计可能出于如下的考虑首先在每次读写全部文件时都会遇到文件结束的 结果如果使用异常那么每次都要为异常处理付出代价其次所有的字符都是无符号 的,因此也存在一个不会和正常情况相混淆的-1. DataInput din =new DataInputStream(fin) try int i= din readint(i long 1 = din. readtong() float f afLoat() double d din. readDouble()i boolean a b= din. readBoolean()i stem out. prinzIn(i)i g catch (ECFException e) //reach end of file catch (ICException ioe) i /7co somethin DataInput接口用于从二进制流中读取字节,并根据所有Java基本类型数据进行 重构 对于此接口中的所有数据读取例程来说,如果在读取所需字节数之前已经到达文件 末尾( end of file),则将抛出 EOFEXception( IOEXception的种)。如果因为 到达文件末尾以外的其他原因无法读取字节,则将抛出 IOException而不是 EOFException。尤其是,在输入流已关闭的情况下,将抛出 IOException。 Datainput接口的 readIntO, readLongO, read Float0, read double0等方法都抛出 EOFEXception来表示到达了文件未尾因为读取的是不同的数据类型所以不存在 个特殊的返回值来标识文件未尾.另一方面数据文件格式通常是已知的,在代码中 读取到最后一个数据自然就到了文件末尾,不需要额外的处理只要数据文件的格式 正确的,就不会有 EOFEXception抛出因此异常发生的频率也不像读写随机文件那 么频繁 另外常用的遍历集合的经典写法是另一个避免使用昇常的很好的例子 for(Iterator i=citerator(, i has Nexto,)

...展开详情
img

关注 私信 TA的资源

上传资源赚积分,得勋章
最新资源