有時候只使用一個異常處理不完全解決程序中出現的異常,需要多個異常處理,這就需要多重catch來實現。
一段代碼可能會生成多個異常當引發異常時,會按順序來查看每個 catch 語句,並執行第一個類型與異常類型匹配的語句執行其中的一條 catch 語句之后,其他的 catch 語句將被忽略。
多重catch語法如下:
try{
//正常程序處理語句
} catch(ArrayIndexOutOfBoundsException e) {
//系統子類異常
} catch(Exception e) {
//系統基類異常
}
注意:
1. 一段代碼可能會生成多個異常
2. 當引發異常時,會按順序來查看每個 catch 語句,並執行第一個類型與異常類型匹配的語句
3. 執行其中的一條 catch 語句之后,其他的 catch 語句將被忽略。
特別注意:在一系列catch語句中,異常子類應該位於其父類之前。否則,不但會產生不能實現的代碼,而且將發生編譯錯誤。
如我們在上文實例中:0作為除數則會引發DivideByZeroException類型的異常,上例中的catch語句可以作如下修改:
catch(DivideByZeroException e)
{
System.Console.WriteLine("零不能作為除數!異常值為:\n{0}",e);
}
catch(Exception e)
{
System.Console.WriteLine("並非\""""零作為除數引發的異常\"!異常值為:\n{0}",e);
}
為什么還要加上一個catch(Exception e)子句呢?原因很簡單,catch(DivideByZeroException e)子句只能捕獲特定的異常,try內的程序代碼可能還會產生其它的異常,這些異常只能由catch(Exception e)來捕獲了。
存在多個catch時,try塊中出現異常后,系統將從距離try塊最近的catch塊中查找相應的異常處理語句,如果匹配成功,就執行catch塊中的異常處理語句,執行完之后,不再執行其他catch塊中的異常處理語句,這個查找過程是從上到下的,主要是檢查catch后面括號中的異常對象是否和系統捕獲到的異常兼容。上面語句中有兩個catch塊,其中后面一個異常處理中Exception是所有異常類的基類,其能夠兼容任何異常對象。如果把Exception放在try后面的第一個catch塊中,則其后面的所有catch語句不能被執行,所以通常把具體的異常放在前面,把基類放在最后的catch塊中。
基類可以捕獲所有異常,我們可能會想:既然基類可以捕獲所有異常,是不是只寫一個Exceotion就可以解決問題了呢?在實際應用中,一般不會這樣處理。打一比方,一所綜合性醫院有很多科室,每個科專門處理不同的病情,眼科醫生擅長眼睛方面疾病,可以把Exception看做全科醫生,名個派生的基類分別屬於不同的專業科室,去醫院看病總是選擇最匹配的科室,為眼睛首先會選擇眼科,而不會去找全科醫生,雖然全科醫生也是可以治眼病,但是畢竟不夠專業。在異常處理中,也是首先選擇各個專業的異常類,Exception放在最后。