1.當(dāng)拋出異常后,有幾件事會隨之發(fā)生。首先,同 Java 中其他對象的創(chuàng)建,將使用 new 在堆上異常對象。然后,當(dāng)前執(zhí)行志新路徑被終止,并從當(dāng)前環(huán)境中彈出異常對象的引用。
拋出一個異常,就像這段代碼這樣:
if(t == null)
throw new NullPointException();
2.所有標(biāo)準(zhǔn)異常類都有兩個構(gòu)造,一個像是上面那樣的無參構(gòu)造,另一個則是接受字符串作為參數(shù),以便能把相關(guān)信息放入異常對象的構(gòu)造。
// 無參構(gòu)造
if(t == null)
throw new NullPointException();
// 傳入 String 的構(gòu)造
throw new NullPointException(“t = null”);
3.從效果上看,它就是像從方法“返回”的,可以簡單地把異常處理看成是一種的返回機(jī)制,但別過分強(qiáng)調(diào)。
4.上面說了如何拋出一個異常,那么下面來說說如何捕獲異常,將可能出現(xiàn)異常的代碼放在 try{} 塊中,而 try{} 塊并不是單獨出現(xiàn)的。
// 一般在將問題的代碼放在 try{} 中,而異常的處理放在 catch{} 中
try {
// 可能發(fā)生異常的代碼
......
} catch(異常類型1 e1) {
// 針對異常類型1 做出的相應(yīng)處理
......
} catch(異常類型2 e2) {
// 針對異常類型2 做出的相應(yīng)處理
......
} // .... 等等
// 如果我們想捕獲所有異常則需要將具體異常類型改為 Exception
try {
// 可能發(fā)生異常的代碼
......
} catch(Exception e) {
// 做出的相應(yīng)處理
......
}
5.自定義異常要繼承自已有的異常類。
6.throws 與 throw 的用途。
(1)throws 某個方法拋出異常
// 可拋出多個異常
void f() throws XXX, XXXX.... {}
(2)throw 語句中拋出異常
throw new XXX();
throw new XXX(“xxxx”);
7.重新拋出異常,異常會返回到上一級環(huán)境中,代碼如下:
try {
// 可能發(fā)生異常的代碼
......
} catch(Exception e) {
throw e; // 拋給上一級環(huán)境
}
8.運行時異常會自動被 Java 虛擬機(jī)拋出,如 NullPointException。
9.finally 的作用:無論 try 塊中異常是否拋出,都希望某些代碼得到執(zhí)行,而這些代碼放在 finally 中就可以實現(xiàn)這樣的需求了。
10.所以一般捕獲到異常的執(zhí)行順序就是 try -> catch -> finally。
11.如果 try-catch 中存在返回語句,那么 finally 依然會得到執(zhí)行,除非在這之前退出了 JVM 虛擬機(jī)。
12.異常丟失的兩種情況:
// 情況一
try {
try {
throw new XXXException();
} finally {
throw new YYYException();
}
} catch(Exception e) {
// 這時候 catch 只能捕獲到 YYYException,而 XXXException 丟失了
}
// 情況二
try {
throw new XXXException();
} finally {
return;
}
13.異常匹配,如果存在多個 catch 塊,則拋出異常時,異常處理系統(tǒng)會按照代碼的書寫順序找出“最近”的處理程序。扎到匹配的處理程序之后,系統(tǒng)就認(rèn)為異常得到了處理,不在繼續(xù)查找。
14.好的程序設(shè)計語言能版程序員寫出好程序,但不論哪種語言都避免不了程序員用它寫出壞程序。
15.將異常傳遞給控制臺,也就是在 main() 方法拋出異常,代碼如下:
public static void main(String[] args) throws Exception {}
16.異常使用指南(摘自書中):
(1)在恰當(dāng)?shù)募墑e處理問題(在知道該如何處理的情況下才能捕獲異常)。
(2)解決問題并且重新調(diào)用產(chǎn)生異常的方法。
(3)進(jìn)行少許修補(bǔ),然后繞過異常發(fā)生的地方繼續(xù)執(zhí)行。
(4)用別的數(shù)據(jù)進(jìn)行計算,以代替方法預(yù)計會返回的值。
(5)把當(dāng)前運行環(huán)境下能做事情盡量做完,然后把相同的異常重拋到更高層。
(6)把當(dāng)前運行環(huán)境下能做事情盡量做完,然后把不同的異常拋到更高層。
(7)終止程序。
(8)進(jìn)行簡化(如果你的異常模式是問題變得太復(fù)雜,那用起來會非常痛苦也很煩人)。
(9)讓類庫和程序更安全(這既是在位調(diào)試做短期投資,也是在為程序的健壯性做長期投資)。