异常
异常能使错误处理代码变得更有条理,只需在一个地方处理错误。把“描述做什么事”的代码和“出了问题怎么办”的代码相分离。先在一个地方专注于正在解决的问题,然后在别的地方处理这些代码中可能发生的错误。
异常情形,在当前环境下无法获得必要的信息来解决问题。
Java将使用 new在堆上创建异常对象。当前的执行路径被终止,并且从当前环境中弹出异常对象的引用。异常处理机制接管程序,异常处理程序继续执行程序。
所有标准异常类都有两个构造器:一个是缺省构造器;另一个是接受字符串作为参数,用来把相关信息放入异常对象的构造器。
创建一个代表错误信息的对象,并且将它从当前环境中“抛出”,这样就把错误信息传播到了“更大”的环境中,称为“抛出一个异常”。
因为异常返回的“地点”与普通方法调用返回的“地点”完全不同。异常将在一个恰当的异常处理程序中得到解决。
“终止模型”,一旦异常被抛出,程序无法返回到异常发生的地方继续执行。
自定义异常
class SimpleException extends Exception {},让编译器为你产生缺省构造器。对异常来说,最重要的部分就是类型的名称。System.err打印到控制台的标准错误流。
异常说明使用了附加的关键字
throws,后面接一个所有潜在异常类型的列表,可以声明方法将抛出异常,实际上却不抛出。
通过捕获异常类型的基类Exception,捕获所有类型的异常。
String getMessage( )
String getLocalizedMessage( )
用来获取详细信息,或用本地语言表示的详细信息。
String toString( )
返回对 Throwable的简单描述,要是有详细信息的话,也会把它包含在内。
void printStackTrace( )
输出到标准输出流,打印Throwable和Throwable的调用栈轨迹。调用栈显示了“把你带到异常抛出地点”的方法调用序列。
重新抛出异常
重抛异常会把异常抛给上一级环境中的异常处理程序。同一个 try 块的后续 catch 子句将被忽略。
Throwable类被用来表示任何可以作为异常被抛出的类。
Throwable对象可分为两类:Error编译期和系统错误;Exception 是可以被抛出的基本类型。
异常的基本的概念是用名称代表发生的问题,并且异常的名称应该可以望文生意。
运行期异常RuntimeException,属于错误将被自动捕获。只能在代码中忽略 RuntimeException(及其子类)类型的异常,其它类型异常的处理都是由编译器强制实施的。
异常被设计用来处理运行期错误,这些错误往往是由你的代码控制能力之外的因素导致的。
finally当你要把除内存之外的资源恢复到它们的初始状态时,就要用到 finally子句。
编译器会对异常说明做强制要求,但异常说明本身并不属于方法原型的一部分,方法原型是由方法的名字与参数的类型组成的。因此,你不能根据异常说明的不同来重载方法。
一个出现在基类方法的异常说明中的异常,不一定会出现在派生类方法的异常说明里。
并不要求抛出的异常同处理程序所声明的异常完全匹配。派生类的对象也可以匹配处理程序中声明的基类。,catch(Annoyance e)会捕获 Annoyance以及所有从它派生的异常。
异常处理的一个重要目标就是把错误处理的代码同错误发生的地点相分离。
异常使用指南:
1.
在恰当的级别处理问题。(在你知道该如何处理的情况下才捕获异常)。
2.
解决问题并且重新调用产生异常的方法。
3.
进行少许修补,然后绕过异常发生的地方继续执行。
4.
用别的数据进行计算,以代替方法返回的期望值。
5.
把当前运行环境下能做的事情尽量作完,然后把相同的异常重抛(rethrow)到
更高层。
6.
把当前运行环境下能做的事情尽量作完,然后把不同的异常抛(throw)到更高
层。
7.
终止程序。
8.
进行简化。(如果异常把问题搞得太复杂,那用起来会非常痛苦也很烦人。)
9.
让类库和程序更安全。(这既是在为调试做短期投资,也是在为程序的健壮性做
长期投资。)