引言:
异常处理已经成为判断一门编程语言是否成熟的标准,它可以使得异常处理代码和业务逻辑代码分离,保证程序更加优雅,提高程序的容错性,使其更加健壮。
下面咱们一起总结下,在Java中关于异常的知识体系。咱们从几个基本问题开始
什么是异常?
定义:一个异常,是在程序执行期间发生的一个事件,它破坏了正常的程序指令流程。
分类
Runtime
checked
指导原则:如果客户端可以合理地预期从异常中恢复,请将其作为已检查的异常。如果客户端无法从异常中恢复,请将其作为未经检查的异常。
error
异常是从哪儿来的(为什么产生异常)?
异常处理的原理,流程
当应用程序出现异常时,系统自动生成一个异常对象,该对象被提交给Java Runtime,这个过程称为异常的抛出。
当Java Runtime收到这个异常对象,首先去寻找能够处理该异常对象的catch代码块,如果找到则交给它进行处理,这个过程被称为异常的捕获。
如果,Java Runtime 找不到能够捕获异常的catch块儿,那么会造成Runtime的终止,程序的退出。
异常最终要到哪儿去?
- 死法一:被处理掉,程序继续运行
- 死法二:一层层被抛弃,没人处理,最终程序终止
为什么要处理异常?
- 好处一:将错误处理代码与“常规”代码分开
- 好处二:更好地调试和改进你的程序,因为它提供了报告发生错误的方法调用堆栈的能力。
- 好处三:分组和区分错误类型
总而言之:这样做,不仅仅使得我们的程序容错性好,更加健壮。而且,提供了更好的可读性。
Java中如何处理异常?
处理的策略
捕获并自行处理
捕获,自己不处理,往上抛
throw or throws
- throws:(用于checked异常处理)只能在方法签名中使用,可抛出多个异常类。且有限制,“两小原则”:子类抛出的应为父类的子类或者相同,且 数量应小于父类
- throw:通常用于自定义异常处理中。通常结合catch一起用。使用异常链。
处理机制
try-catch-finally
try
catch
- 捕获多个异常
- 访问异常
- 先捕获小异常,后捕获大异常
finally
- 回收资源(物理资源,例如:数据库连接、网络连接、磁盘文件等)
- 被改建的try语句(可以用来替代finally的作用),在try中使用括号,因为进行物理资源调用的类都实现了AutoCloseable或者Closeable接口
注意:无论如何,这个块儿里面代码总是会被执行(除非使用exit 语句退出虚拟机)。而且,不要在里面使用return、throw等导致方法终止的语句,因为这样会导致无法回到try、catch代码块中的继续执行。
异常类的继承体系
checked和Runtime异常
指导原则:如果客户端可以合理地预期从异常中恢复,请将其作为已检查的异常。如果客户端无法从异常中恢复,请将其作为未经检查的异常。
利用异常跟踪栈,调试程序
但是,应在最后发布的程序中使用它,应该对捕获的异常进行适当的处理,而不是简单打印异常的堆栈。
处理的规则(优化角度)
- 不要过度使用
- 不要使用大块儿的try,而应该使用多个小块儿的try
- 避免使用catch all 语句(能够处理所有可能发生的异常),因为:第一,要分类处理各种不同情况的异常。第二,这种方式经常会忽略一些关键的异常,产生不可估计的损失。
- 不要忽略捕获到的异常(不能在catch中为空,也不能直接打印堆栈),应该:处理异常,要么对其进行合适的修复,要么提示用户重新操作。。。或者,重新抛出一个新的经过包装的异常。或者在合适的层进行处理。
实战demo:
http://www.360doc.com/content/15/0302/09/7992420_451890164.shtml