“擲”出一個違例後,違例控制系統會按當初編寫的順序搜索“最接近”的控制器。一旦找到相符的控制器,就認為違例已得到控制,不再進行更多的搜索工作。
在違例和它的控制器之間,並不需要非常精確的匹配。一個衍生類對象可與基礎類的一個控制器相配,如下例所示:
//: Human.java // Catching Exception Hierarchies class Annoyance extends Exception {} class Sneeze extends Annoyance {} public class Human { public static void main(String[] args) { try { throw new Sneeze(); } catch(Sneeze s) { System.out.println("Caught Sneeze"); } catch(Annoyance a) { System.out.println("Caught Annoyance"); } } } ///:~
Sneeze違例會被相符的第一個catch從句捕獲。當然,這只是第一個。然而,假如我們刪除第一個catch從句:
try { throw new Sneeze(); } catch(Annoyance a) { System.out.println("Caught Annoyance"); }
那麼剩下的catch從句依然能夠工作,因為它捕獲的是Sneeze的基礎類。換言之,catch(Annoyance e)能捕獲一個Annoyance以及從它衍生的任何類。這一點非常重要,因為一旦我們決定為一個方法添加更多的違例,而且它們都是從相同的基礎類繼承的,那麼客戶程序員的代碼就不需要更改。至少能夠假定它們捕獲的是基礎類。
若將基礎類捕獲從句置於第一位,試圖“屏蔽”衍生類違例,就象下面這樣:
try { throw new Sneeze(); } catch(Annoyance a) { System.out.println("Caught Annoyance"); } catch(Sneeze s) { System.out.println("Caught Sneeze"); }
則編譯器會產生一條出錯消息,因為它發現永遠不可能抵達Sneeze捕獲從句。