Thinking in Java 第十二章通过异常处理错误读书
1.当抛出异常后,有几件事会随之发生。首先,同 Java 中其他对象的创建,将使用 new 在堆上异常对象。然后,当前执行志新路径被终止,并从当前环境中弹出异常对象的引用。
抛出一个异常,就像这段代码这样:
if(t == null)
throw new NullPointException();
2.所有标准异常类都有两个构造,一个像是上面那样的无参构造,另一个则是接受字符串作为参数,以便能把相关信息放入异常对象的构造。
// 无参构造
if(t == null)
throw new NullPointException();
// 传入 String 的构造
throw new NullPointException(“t = null”);
3.从效果上看,它就是像从方法“返回”的,可以简单地把异常处理看成是一种的返回机制,但别过分强调。
4.上面说了如何抛出一个异常,那么下面来说说如何捕获异常,将可能出现异常的代码放在 try{} 块中,而 try{} 块并不是单独出现的。
// 一般在将问题的代码放在 try{} 中,而异常的处理放在 catch{} 中
try {
// 可能发生异常的代码
......
} catch(异常类型1 e1) {
// 针对异常类型1 做出的相应处理
......
} catch(异常类型2 e2) {
// 针对异常类型2 做出的相应处理
......
} // .... 等等
// 如果我们想捕获所有异常则需要将具体异常类型改为 Exception
try {
// 可能发生异常的代码
......
} catch(Exception e) {
// 做出的相应处理
......
}
5.自定义异常要继承自已有的异常类。
6.throws 与 throw 的用途。
(1)throws 某个方法抛出异常
// 可抛出多个异常
void f() throws XXX, XXXX.... {}
(2)throw 语句中抛出异常
throw new XXX();
throw new XXX(“xxxx”);
7.重新抛出异常,异常会返回到上一级环境中,代码如下:
try {
// 可能发生异常的代码
......
} catch(Exception e) {
throw e; // 抛给上一级环境
}
8.运行时异常会自动被 Java 虚拟机抛出,如 NullPointException。
9.finally 的作用:无论 try 块中异常是否抛出,都希望某些代码得到执行,而这些代码放在 finally 中就可以实现这样的需求了。
10.所以一般捕获到异常的执行顺序就是 try -> catch -> finally。
11.如果 try-catch 中存在返回语句,那么 finally 依然会得到执行,除非在这之前退出了 JVM 虚拟机。
12.异常丢失的两种情况:
// 情况一
try {
try {
throw new XXXException();
} finally {
throw new YYYException();
}
} catch(Exception e) {
// 这时候 catch 只能捕获到 YYYException,而 XXXException 丢失了
}
// 情况二
try {
throw new XXXException();
} finally {
return;
}
13.异常匹配,如果存在多个 catch 块,则抛出异常时,异常处理系统会按照代码的书写顺序找出“最近”的处理程序。扎到匹配的处理程序之后,系统就认为异常得到了处理,不在继续查找。
14.好的程序设计语言能版程序员写出好程序,但不论哪种语言都避免不了程序员用它写出坏程序。
15.将异常传递给控制台,也就是在 main() 方法抛出异常,代码如下:
public static void main(String[] args) throws Exception {}
16.异常使用指南(摘自书中):
(1)在恰当的级别处理问题(在知道该如何处理的情况下才能捕获异常)。
(2)解决问题并且重新调用产生异常的方法。
(3)进行少许修补,然后绕过异常发生的地方继续执行。
(4)用别的数据进行计算,以代替方法预计会返回的值。
(5)把当前运行环境下能做事情尽量做完,然后把相同的异常重抛到更高层。
(6)把当前运行环境下能做事情尽量做完,然后把不同的异常抛到更高层。
(7)终止程序。
(8)进行简化(如果你的异常模式是问题变得太复杂,那用起来会非常痛苦也很烦人)。
(9)让类库和程序更安全(这既是在位调试做短期投资,也是在为程序的健壮性做长期投资)。