Java的基本理念是”结构不佳的代码不能运行” ——《Java编程思想》
1.异常基本原理
if(t==null){
//所有标准异常类都有两个构造器:一个默认构造器;一个接受字符串作为参数
throw new NullPointerException("t==null");
}
上面这段代码抛出异常后,有几件事会随之发生:
- 使用new在堆上创建异常对象。
- 当前的执行路径被终止,并从当前环境中弹出对异常对象的引用。
- 异常处理机制接管程序,并开始寻找一个恰当的地方来继续执行程序。这个恰当的地方就是异常处理程序,它的任务是将程序从错误状态中恢复,以使程序能要么换一种方式运行,要么继续运行下去。
关键字throw将产生很多有趣的结果。使用new创建了异常对象后,此对象的引用将传给throw。即使返回的异常对象类型和方法设计的返回类型不同,但从效果上看,它就像是从方法”返回”的一样。可以简单的把异常处理看成一种不同的返回机制。
抛出异常与方法正常返回值的相似之处仅此而已。因为异常返回的”地点”与普通方法调用返回的”地点”完全不同。 异常将在一个恰当的异常处理程序中得到解决,它的位置可能离异常被抛出的地方很远,也可能会跨越方法调用栈的许多层级。
2.终止和恢复
异常处理try/catch理论上有两种基本模型。
- 终止模型:在这种模型中,将假设错误非常关键,以至于程序无法返回到异常发生的地方继续执行,一旦异常被抛出,就表明错误已无法挽回,也不能回来继续执行。
- 恢复模型:意思是异常处理程序的工作是修正错误,重新调用出问题的方法,并认为重新调用能成功。如果要利用Java做这种类似恢复的行为,那么遇见错误就不能抛出异常,而是调用方法来修正该错误。或者,把try块放在while循环里,这样不断进入try块直到得到满意的结果。
长久以来,尽管操作系统和Java语言支持恢复模型的异常处理,并且恢复模型看起来很吸引人,但不是很实用。其中主要原因可能是它所导致的耦合:恢复性的处理程序需要了解异常抛出的地点,这势必要包含依赖于抛出位置的非通用型带,增加了代码编写和维护的难度。所以程序员们最终还是使用终止模型,并且忽略恢复模型。