异常处理总结.docx
- 文档编号:8181558
- 上传时间:2023-01-29
- 格式:DOCX
- 页数:9
- 大小:56.37KB
异常处理总结.docx
《异常处理总结.docx》由会员分享,可在线阅读,更多相关《异常处理总结.docx(9页珍藏版)》请在冰豆网上搜索。
异常处理总结
异常处理
1、为什么要引入异常处理机制
我们的程序在编译或运行时可能会出问题,当出现问题的时候程序就死掉了,这样的程序健壮性不好。
因此在JAVA中我们引入了异常处理机制,既保证能及时发现问题并加以纠正,又能保证程序不死掉。
JAVA中保证程序健壮性的方式有三种:
Ø垃圾回收机制(保证不会发生内存泄露)
Ø弃用指针(保证不能直接对底层进行操作)
Ø异常处理机制(保证程序不会因发生异常而死掉)
2、什么是异常处理机制
2.1、异常的定义
程序问题的分类:
Ø错误(Error):
严重的错误,无法通过修改代码来处理。
如JVM运行失败、线程池出错导致JVM无法正确运行。
Ø异常(Exception):
异常表示程序执行过程中出现的不正常的现象,可以通过修改代码来进行弥补。
⏹异常的分类:
◆运行时异常(unchecked):
运行时异常都是RuntimeException类及其子类异常,如NullPointerException、IndexOutOfBoundsException等,这些异常是不检查异常,程序中可以选择捕获处理,也可以不处理。
这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生。
◆编译时异常(checked):
编译时异常是RuntimeException以外的异常,类型上都属于Exception类及其子类。
从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。
如IOException、SQLException等以及用户自定义的Exception异常,一般情况下不自定义检查异常。
⏹异常处理的顺序:
◆引发异常(检测异常情况并生成异常的过程叫引发异常)
◆捕获异常(当异常被引发时,可被处理程序捕获)
◆处理异常(上面的两个过程总称为处理异常)
2.2、异常的捕获和处理机制
Java异常处理涉及到五个关键字,分别是:
try、catch、finally、throw、throws
Ø一个异常处理块的通常语法形式:
Try{
//可能引发异常的语句
}
Catch(ExceptionType1ex){
//获得此类异常信息并处理异常的代码
}
Catch(ExceptionType2ex){
//获得此类异常信息并处理异常的代码
}
(注意:
Catch块的放置顺序,捕获子类异常放前面,捕获父类异常放后面)
…………
Finally{
//一般为释放资源的语句
}
⏹以上语法有三个代码块:
try语句块,表示要尝试运行代码,try语句块中代码受异常监控,其中代码发生异常时,会抛出异常对象。
⏹异常处理的代码执行顺序有两种
◆不发生异常时:
●执行完Try块里的语句后跳过Catch块,执行Finally里面的语句;若Try块中有return语句是,先执行Finally里的语句,再执行return;若Try块中有Sistem.exit()语句时将直接结束程序,不执行Finally里的语句。
◆当发生异常时:
●catch语句带一个Throwable类型的参数,表示可捕获异常类型。
当try中出现异常时,catch会捕获到发生的异常,并和自己的异常类型匹配,若匹配,则执行catch块中代码,并将catch块参数指向所抛的异常对象。
●catch语句可以有多个,用来匹配多个中的一个异常,一旦匹配上后,就不再尝试匹配别的catch块了。
通过异常对象可以获取异常发生时完整的JVM堆栈信息,以及异常信息和异常发生的原因等。
●finally语句块是紧跟catch语句后的语句块,这个语句块总是会在方法返回前执行,而不管是否try语句块是否发生异常。
并且这个语句块总是在方法返回前执行。
目的是给程序一个补救的机会。
这样做也体现Java语言的健壮性。
ØTryCatchFinally使用时应注意的问题:
⏹try、catch、finally三个语句块均不能单独使用,三者可以组成try...catch...finally、try...catch、try...finally三种结构,catch语句可以有一个或多个,finally语句最多一个。
⏹try、catch、finally三个代码块中变量的作用域为代码块内部,分别独立而不能相互访问。
如果要在三个块中都可以访问,则需要将变量定义到这些块的外面。
⏹多个catch块时候,只会匹配其中一个异常类并执行catch块代码,而不会再执行别的catch块,并且匹配catch语句的顺序是由上到下。
Øthrow、throws关键字的用法和对比:
⏹throw关键字是用于方法体内部,用来抛出一个Throwable类型的异常。
如果抛出了检查异常,则还应该在方法头部声明方法可能抛出的异常类型。
该方法的调用者也必须检查处理抛出的异常。
如果所有方法都层层上抛获取的异常,最终JVM会进行处理,处理也很简单,就是打印异常消息和堆栈信息。
如果抛出的是Error或RuntimeException,则该方法的调用者可选择处理该异常。
⏹throws关键字用于方法体外部的方法声明部分,用来声明方法可能会抛出某些异常。
仅当抛出了检查异常,该方法的调用者才必须处理或者重新抛出该异常。
当方法的调用者无力处理该异常的时候,应该继续抛出,而不是囫囵吞枣一般在catch块中打印一下堆栈信息做个勉强处理。
⏹一般来说,写了throw一定要写throws,而写了throws不一定要写throw。
⏹throw、throws关键字的用法举例:
publicstaticvoidtest()throwsException{
//抛出一个检查异常
thrownewException("方法test中的Exception");
}
Ø关于异常类:
⏹异常类是和其他类一样的类,java.lang.Throwable类是所有异常类的根类
⏹java.lang.Throwable类有两个扩展类,分别是Error类和Exception类
⏹JAVA中大多数异常类都使用Exception类
Java异常体系结构图
Java的Java.lang中定义的运行时异常
异常
说明
ArithmeticException
算术错误,比如被0除
ArrayIndexOutOfBoundsException
数组下标出界
ArrayStoreException
数组元素赋值类型不兼容
ClassCastException
非法强制转换类型
IllegalArgumentException
调用方法的参数非法
IllegalMonitorStateException
非法监控操作,如等待一个未锁定线程
IllegalStateException
环境或应用状态不正确
IllegalTheadStateException
请求操作与当前线程状态不兼容
IndexOutBoundsException
某些类型索引越界
NullPointerException
非法使用空引用
NumberFormatException
字符串到数字格式非法转换
SecurityException
试图违反安全性
StringIndexOurOfBounds
试图在字符串边界之外索引
UnsurpportedOperationException
遇到不支持的操作
Java的Java.lang中定义的编译时异常
异常
说明
ClassNotFoundException
找不到类
CloneNotSupportedException
试图克隆不能实现Cloneable接口的对象
IllegalAccessException
对一个类的访问被拒绝
InstantiationException
试图创建一个抽象类或抽象接口的对象
InterruptedException
一个线程被另一个线程中断
NoSuchFieldException
请求的字段不存在
NoSuchMethodException
请求的方法不存在
Throwable类中常用的核心方法
方法
描述
ThrowablefillInStackTrace()
填充该执行堆栈跟踪
StringgetLocalizedMessage()
创建该可引发类的本地化描述
StringgetMessage()
返回该可引发对象的错误消息字符串
VoidprintStackTrace
将可引发类及其反向跟踪打印到标准错误输出流
VoidprintStackTrace(PrintStreams)
将该可引发类及其反向跟踪打印到指定的打印流
VoidprintStackTrace(PrintWriters)
将该可引发类及其反向跟踪打印到指定的打印机
StringtoString
返回关于该可引发类的简短描述
2.3、异常处理的一般原则
Ø能处理就早处理,抛出不去还不能处理的就想法消化掉或者转换为RuntimeException处理。
因为对于一个应用系统来说,抛出大量异常是有问题的,应该从程序开发角度尽可能的控制异常发生的可能。
Ø对于检查异常,如果不能行之有效的处理,还不如转换为RuntimeException抛出。
这样也让上层的代码有选择的余地――可处理也可不处理。
Ø对于一个应用系统来说,应该有自己的一套异常处理框架,这样当异常发生时,也能得到统一的处理风格,将优雅的异常信息反馈给用户。
2.4、异常的转义与异常链
Ø所谓的异常转译就是将一种异常转换另一种新的异常,也许这种新的异常更能准确表达程序发生异常。
⏹在Java中有个概念就是异常原因,异常原因导致当前抛出异常的那个异常对象,几乎所有带异常原因的异常构造方法都使用Throwable类型做参数,这也就为转义异常提供了直接的支持,因为任何形式的异常和错误都是Throwable的子类。
。
比如将SQLException转换为另外一个新的异常DAOException,可以这么写:
先自定义一个异常DAOException:
publicclassDAOExceptionextendsRuntimeException{
//(一般来说都要写一下4个构造方法)
publicDAOException(){
super();
}
publicDAOException(Exceptionex){
super(Exceptionex);
}
publicDAOException(Throwableth){
super(Throwableth);
}
publicDAOException(Stringstr){
super(Stringstr);
}
}
比如有一个SQLException类型的异常对象e,要转换为DAOException,可以这么写:
DAOExceptiondaoEx=newDAOException("SQL异常"e);
Ø异常链顾名思义就是将异常发生的原因一个传一个串起来,即把底层的异常信息传给上层,这样逐层抛出。
⏹当程序捕获到了一个底层异常le,在处理部分选择了继续抛出一个更高级别的新异常给此方法的调用者。
这样异常的原因就会逐层传递。
这样,位于高层的异常递归调用getCause()方法,就可以遍历各层的异常原因。
这就是Java异常链的原理。
异常链的实际应用很少,发生异常时候逐层上抛不是个好注意,上层拿到这些异常又能奈之何?
而且异常逐层上抛会消耗大量资源,因为要保存一个完整的异常链信息。
3、设计一个高效合理的异常处理框架
对于一个应用系统来说,发生所有异常在用户看来都是应用系统内部的异常。
因此应该设计一套应用系统的异常框架,以处理系统运行过程中的所有异常。
基于这种观点,可以设计一个应用系统的异常比如叫做AppException。
并且对用户来说,这些异常都是运行应用系统运行时发生的,因此AppException应该继承RuntimeException,这样系统中所有的其他异常都转译为AppException,当异常发生的时候,前端接收到AppExcetpion并做统一的处理。
画出异常处理框架如下图:
一个应用系统的异常处理框架
在这个设计图中,AppRuntimeException是系统异常的基类,对外只抛出这个异常,这个异常可以由前端(客户端)接收处理,当异常发生时,客户端的相关组件捕获并处理这些异常,将"友好"的信息展示给客户。
在AppRuntimeException下层,有各种各样的异常和错误,最终都转译为AppRuntimeException,AppRuntimeException下面还可以设计一些别的子类异常,比如AppDAOException、OtherException等,这些都根据实际需要灵活处理。
在往下就是如何将捕获的原始异常比如SQLException、HibernateException转换为更高级一点AppDAOException。
有关异常框架设计这方面公认比较好的就是Spring,Spring中的所有异常都可以用org.springframework.core.NestedRuntimeException来表示,并且该基类继承的是RuntimeException。
Spring框架很庞大,因此设计了很多NestedRuntimeException的子类,还有异常转换的工具,这些都是非常优秀的设计思想。
4、Java异常处理总结
Ø异常是程序运行过程过程出现的错误,在Java中用类来描述,用对象来表示具体的异常。
Java将其区分为Error与Exception,Error是程序无力处理的错误,Exception是程序可以处理的错误。
异常处理是为了程序的健壮性。
ØJava异常类来自于JavaAPI定义和用户扩展。
通过继承JavaAPI异常类可以实现异常的转译。
Ø异常能处理就处理,不能处理就抛出,最终没有处理的异常JVM会进行处理。
Ø异常可以传播,也可以相互转译,但应该根据需要选择合理的异常转译的方向。
Ø对于一个应用系统,设计一套良好的异常处理体系很重要。
这一点在系统设计的时候就应该考虑到。
出师表
两汉:
诸葛亮
先帝创业未半而中道崩殂,今天下三分,益州疲弊,此诚危急存亡之秋也。
然侍卫之臣不懈于内,忠志之士忘身于外者,盖追先帝之殊遇,欲报之于陛下也。
诚宜开张圣听,以光先帝遗德,恢弘志士之气,不宜妄自菲薄,引喻失义,以塞忠谏之路也。
宫中府中,俱为一体;陟罚臧否,不宜异同。
若有作奸犯科及为忠善者,宜付有司论其刑赏,以昭陛下平明之理;不宜偏私,使内外异法也。
侍中、侍郎郭攸之、费祎、董允等,此皆良实,志虑忠纯,是以先帝简拔以遗陛下:
愚以为宫中之事,事无大小,悉以咨之,然后施行,必能裨补阙漏,有所广益。
将军向宠,性行淑均,晓畅军事,试用于昔日,先帝称之曰“能”,是以众议举宠为督:
愚以为营中之事,悉以咨之,必能使行阵和睦,优劣得所。
亲贤臣,远小人,此先汉所以兴隆也;亲小人,远贤臣,此后汉所以倾颓也。
先帝在时,每与臣论此事,未尝不叹息痛恨于桓、灵也。
侍中、尚书、长史、参军,此悉贞良死节之臣,愿陛下亲之、信之,则汉室之隆,可计日而待也。
臣本布衣,躬耕于南阳,苟全性命于乱世,不求闻达于诸侯。
先帝不以臣卑鄙,猥自枉屈,三顾臣于草庐之中,咨臣以当世之事,由是感激,遂许先帝以驱驰。
后值倾覆,受任于败军之际,奉命于危难之间,尔来二十有一年矣。
先帝知臣谨慎,故临崩寄臣以大事也。
受命以来,夙夜忧叹,恐托付不效,以伤先帝之明;故五月渡泸,深入不毛。
今南方已定,兵甲已足,当奖率三军,北定中原,庶竭驽钝,攘除奸凶,兴复汉室,还于旧都。
此臣所以报先帝而忠陛下之职分也。
至于斟酌损益,进尽忠言,则攸之、祎、允之任也。
愿陛下托臣以讨贼兴复之效,不效,则治臣之罪,以告先帝之灵。
若无兴德之言,则责攸之、祎、允等之慢,以彰其咎;陛下亦宜自谋,以咨诹善道,察纳雅言,深追先帝遗诏。
臣不胜受恩感激。
今当远离,临表涕零,不知所言。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 异常 处理 总结