宋哲明
1.背景介绍
2.知识剖析
3.常见问题
4.解决方案
5.编码实战
6.扩展思考
7.参考文献
8.更多讨论
可能每一只程序猿都有这样一个梦想
程序永远不会出现问题,用户输入的数据永远是正确的,逻辑一定没有任何问题 ,选择打开的资源也一定是存在的,连接永远是OK的,内存永远是够用的……
简单来说就是:0 error(s), 0 warning(s)
但是,不存在的...
异常处理机制
天有不测风云,人有旦夕祸福,Java的程序代码也如此,JAVA远在设计之初就考虑到了这个问题,于是就设计了JAVA的异常处理机制。而发展至今的异常处理机制现在也已经非常的完善。
什么是异常处理?
如果某个方法不能按照正常的途径完成任务, 就可以通过另一种路径退出方法。 在这种情况下会抛出一个封装了错误信息的对象。 此时,这个方法会立刻退出同时不返回任何值。 另外,调用这个方法的其他代码也无法继续执行, 异常处理机制会将代码执行交给异常处理器。
异常的分类
java中的异常机制包括Error和Exception两个部分。他们都继承自一个共同的基类Throwable
Error属于JVM运行中发生的一些错误,虽然并不属于开发人员的范畴,但是有些Error还是由代码引起的,比如StackOverflowError经常由递归操作引起
Exception分为两种,检查类型(checked)和未检查类型(unchecked)。检查类型的异常就是说要程序员明确的去声明或者用try..catch语句来处理的异常,而非检查类型的异常则没有这些限制
换一种说法
对于严重的,java通过Error类来描述
对于Error一般不编写针对性的代码对其进行处理
对于非严重的,java通过Exception类来描述
对于Exception可以使用针对性的处理方式进行处理
Java异常处理涉及到五个关键字,分别是:try、catch、finally、throw与throws,每个关键字不能被单独使用
1.try:它里面放置可能引发异常的代码
2.catch:后面对应异常类型和一个代码块,用于表明该catch块用于处理这种类型的代码块,可以有多个catch块。
3.finally:主要用于回收在try块里打开的物力资源(如数据库连接、网络连接和磁盘文件),异常机制总是保证finally块总是被执行。
4.throw:用于抛出一个实际的异常,可以单独作为语句使用,抛出一个具体的异常对象。
5.throws:用在方法签名中,用于声明该方法可能抛出的异常。
注意点1:只有try块是必须的,也就是说如果没有try块,则不可能有后面的catch块和finally块;
注意点2:catch块和finally块都是可选的,但catch块和finally块至少出现其中之一,也可以同时出现;
注意点3:可以有多个catch块,捕获父类异常的catch块必须位于捕获子类异常的后面;
注意点4:不能只有try块,既没有catch块,也没有finally块;
注意点5:多个catch块必须位于try块之后,finally块必须位于所有catch块之后。
一般情况下,不要再finally块中使用renturn或throw等导致方法终止的语句,因为一旦使用,将会导致try块、catch块中的return、throw语句失效。
错误处理代码和业务实现代码混杂严重影响程序的可读性,会增加程序维护的难度。在代码健壮性和代码可读性上如何抉择?
基于try catch的异常处理机制,比较灵活,比较强大,也比较重。事物都有双面性。try catch 的代价比较大。相对于判断返回值,跑出异常到捕获,需要更多的cpu指令和代码,比如回溯stack检查是否有异常捕获。具体如何实现,可以研究下。try catch的好处是什么?可以携带完整的出错信息。比如出处,错误类型,错误的具体原因等。此外异常还可逆调用链条传递,对异常处理来说可以灵活,即你可以不处理而直接告诉上层。但是应该的自己关心的异常在本层处理掉。同时可以对此异常封装便于纪录根本出错,然后重新抛出。这些你返做会很累而且不清晰。对于编程实践,我觉得,异常应该少用,除非是这种错误会很少出现,即,一旦出现是一种严重的错误,那么抛出异常是合理的。否则用返回码来标志。明显异常是一种不可或缺的编程元素,是将编程中“错误”进行更加精密和正规对待的方式。认识到错误也是编程的重要组成,而不仅仅是附属品。这很关键.任何范式和特性都不能滥用,都不能依赖语言而进行懒惰式,逃避式编程。要写出优秀的程序,是要斟酌和将语言特性视为工具,择而用之。
百度
无法穷举所有异常情况,因为人类的知识是有限的,异常情况总比可以考虑到的情况多,总有漏网之鱼,怎么办?
By:宋哲明