Atitit.java 异常的使用总结最佳实践 Vo8f
2. 用throw抛出一个异常到catch子句中与通过函数调用传递一个参数两者基本相同。 2
4. RuntimeException跟checked Exception 2
8. Base类and 扩展class 抛出的特别的异常不一样的解决之道 4
11. 列举最常用的五种RuntimeException: 5
12. 下面是JDK API中列出的异常类: 除了RuntimeException以外的,都是checked Exception 5
1. 为什么使用异常
对C程序来说,使用Error Code就可以了,为什么还要引入异常?因为异常不能被忽略。如果一个函数通过设置一个状态变量或返回错误代码来表示一个异常状态,没有办法保证函数调用者将一定检测变量或测试错误代码。结果程序会从它遇到的异常状态继续运行,异常没有被捕获,程序立即会终止执行。
在C程序中,我们可以用int setjmp( jmp_buf env );和 void longjmp( jmp_buf env, int value );这2个函数来完成和异常处理相识的功能,但是MSDN中介绍了在C++中使用longjmp来调整stack时不能够对局部的对象调用析构函数,但是对C++程序来说,析构函数是重要的(我就一般都把对象的Delete放在析构函数中)。 <br>所以我们需要一个方法:①能够通知异常状态,又不能忽略这个通知,②并且Searching the stack以便找到异常代码时,③还要确保局部对象的析构函数被Call。而C++的异常处理刚好就是来解决这些问题的。</p> <p>有的地方只有用异常才能解决问题,比如说,在当前上下文环境中,无法捕捉或确定的错误类型,我们就得用一个异常抛出到更大的上下文环境当中去。还有,异常处理的使用呢,可以使出错处理程序与“通常”代码分离开来,使代码更简洁更灵活。另外就是程序必不可少的健壮性了,异常处理往往在其中扮演着重要的角色。</p>
因为当函数返回时局部对象总是被释放,无论函数是如何退出的。(仅有一种例外就是当你调用longjmp时。Longjmp的这个缺点是C++率先支持异常处理的主要原因)
尽管C++首次引入异常的规范
尽管C++首次引入异常的规范,但是Java是强制实施"检查的异常"(Checked Exception)规范的唯一的主流语言
作者:: 老哇的爪子 Attilax 艾龙, EMAIL:1466519819@qq.com
转载请注明来源: http://blog.csdn.net/attilax
2. 用throw抛出一个异常到catch子句中与通过函数调用传递一个参数两者基本相同。
这里面确有一些相同点,但是他们也存在着巨大的差异。</p> <p>让我们先从相同点谈起。你传递函数参数与异常的途径可以是传值、传递引用或传递指针,这是相同的。但是当你传递参数和异常时,系统所要完成的操作过程则是完全不同的。产生这个差异的原因是:你调用函数时,程序的控制权最终还会返回到函数的调用处,但是当你抛出一个异常时,控制权永远不会回到抛出异常的地方。</p>
3. S E H的主要动机
微软在Wi n d o w s中引入S E H的主要动机是为了便于操作系统本身的开发。操作系统的开发人员使用S E H,使得系统更加强壮。我们也可以使用S E H,使我们的自己的程序更加强壮。 <br>使用S E H所造成的负担主要由编译程序来承担,而不是由操作系统承担。 <br>当异常块(exception block)出现时,编译程序要生成特殊的代码。编译程序必须产生一些表( t a b l e)来支持处理S E H的数据结构。 <br>编译程序还必须提供回调( c a l l b a c k)函数,操作系统可以调用这些函数,保证异常块被处理。 <br>编译程序还要负责准备栈结构和其他内部信息,供操作系统使用和参考。 <br>在编译程序中增加S E H支持不是一件容易的事。不同的编译程序厂商会以不同的方式实现S E H,这一点并不让人感到奇怪。幸亏我们可以不必考虑编译程序的实现细节,而只使用编译程序的S E H功能。(其实大多数编译程序厂商都采用微软建议的语法)
4. RuntimeException跟checked Exception
Java的Exception分为两类,一类是RuntimeException及其子类,另外一类就是checked Exception。Java要求函数对没有被catch处理掉的checked Exception,需要将其写在函数的声明部分
.net 只有RuntimeException
除了Error与RuntimeException,其他剩下的异常都是你需要关心的,而这些异常类统称为Checked Exception,至于Error与RuntimeException则被统称为Unchecked Exception.
5. 要不要使用checked Exception
要使用....优点是流程clr,and ide能自动生成结构代码...
中建议在遇到可恢复的错误时采用checked异常,遇到不可恢复的异常时采用unchecked异常。
6. Exception业务流程控制 可以借鉴一下)
在使用UseCase来描述一个场景的时候,有一个主事件流和n个异常流。异常流可能发生在主事件流的过程,而try语句里面实现的是主事件流,而 catch里面实现的是异常流,在这里Exception不代表程序出现了异常或者错误,Exception只是面向对象化的业务逻辑控制方法。如果没有 明白这一点,那么我认为并没有真正明白应该怎么使用Java来正确的编程。
而我自己写的程序,会自定义大量的Exception类,所有这些Exception类都不意味着程序出现了异常或者错误,只是代表非主事件流的发生的, 用来进行那些分支流程的流程控制的。例如你往权限系统中增加一个用户,应该定义1个异常类,UserExistedException,抛出这个异常不代 表你插入动作失败,只说明你碰到一个分支流程,留待后面的catch中来处理这个分支流程。传统的程序员会写一个if else来处理,而一个合格的OOP程序员应该有意识的使用try catch 方式来区分主事件流和n个分支流程的处理,通过try catch,而不是if else来从代码上把不同的事件流隔离开来进行分别的代码撰写
7. checked Exception 的缺点
支持Unchecked异常:
沿调用栈向上传播的Checked异常破坏了顶层的方法,因为这些方法必须声明抛出所有它们调用的方法抛出的异常
Check异常的抛出作为方法接口的一部分,这使得添加或移除早期版本中方法的异常难以实现。
8. Base类and 扩展class 抛出的特别的异常不一样的解决之道
可以在Base类的foo方法中加入抛出ExceptionB的声明,然而,这样就破坏了open-close原则。而且,有时我们没有办法去修改父类,比如当重载一个Jdk里的类的时候。
另一个可能的做法是在Extend的foo方法中catch住ExceptionB,然后构造一个ExceptionA并抛出。这是个可行的办法但也只是一个权宜之计。
9. checked Exception 转换 re
为了避免在函数声明中写throws部分,在Java项目里面常常可以看到以下代码用来‘吞掉’Exception:
10. 丢出新异常D,可以让它从已有的异常中继承,
[iii] 在“The Design and Evolution of C++”, Bjarne Stroustrup也提到,同样也基于对这个问题的考虑,c++没有“Static Checking”(checked exceptions)而是采用“Run time Checking”。而且Stroustrup建议,对于丢出新异常D,可以让它从已有的异常中继承,这样既不影响已有代码,新的代码也可以处理它。(这是Stroustrup在1990就作出的结论!)
11. 列举最常用的五种RuntimeException:
这是JAVA认证考试中最常见的题目,事实上,runtime exception中最常见的,经常碰到的,也就5,6种,如下:
ArithmeticException | int a=0; |
ClassCastException: | Object x = new Integer(0); |
IndexOutOfBoundsException | int [] numbers = { 1, 2, 3 }; |
IllegalArgumentException | int a = Interger.parseInt("test"); |
NullPointerExceptionextends |
· 除了RuntimeException,其他继承自java.lang.Exception得异常统称为Checked Exception,他们有多少种呢?
12. 下面是JDK API中列出的异常类:
除了RuntimeException以外的,都是checked Exception
java.lang.Object |
13. 参考
Anders Hejlsberg论为什么不在c#引入类似java的checked exceptions - 产品和技术 - 赛迪网.htm
C++处理异常技巧.htm
[转载]JAVA 的checked异常和unchecked异常_4527_新浪博客.htm