某些情況,由單個代碼段可能引起多個異常。處理這種情況,你可以定義兩個或更多的catch子句,每個子句捕獲一種類型的異常。當異常被引發時,每一個catch子句被依次檢查,第一個匹配異常類型的子句執行。當一個catch語句執行以后,其他的子句被旁路,執行從try/catch塊以后的代碼開始繼續。下面的例子設計了兩種不同的異常類型:
下面是運行在兩種不同情況下程序的輸出:
C:\>java MultiCatch
a = 0
Divide by 0: java.lang.ArithmeticException: / by zero After try/catch blocks.
C:\>java MultiCatch TestArg
a = 1
Array index oob: java.lang.ArrayIndexOutOfBoundsException After try/catch blocks.
當你用多catch語句時,記住異常子類必須在它們任何父類之前使用是很重要的。這是因為運用父類的catch語句將捕獲該類型及其所有子類類型的異常。這樣,如果子類在父類后面,子類將永遠不會到達。而且,Java中不能到達的代碼是一個錯誤。例如,考慮下面的程序:
1 // Demonstrate multiple catch statements. 2 class MultiCatch { 3 public static void main(String args[]) { 4 try { 5 int a = args.length; 6 System.out.println("a = " + a); 7 int b = 42 / a; 8 int c[] = { 1 }; 9 c[42] = 99; 10 } catch(ArithmeticException e) { 11 System.out.println("Divide by 0: " + e); 12 } catch(ArrayIndexOutOfBoundsException e) { 13 System.out.println("Array index oob: " + e); 14 } 15 System.out.println("After try/catch blocks."); 16 } 17 }
該程序在沒有命令行參數的起始條件下運行導致被零除異常,因為a為0。如果你提供一個命令行參數,它將幸免於難,把a設成大於零的數值。但是它將導致ArrayIndexOutOf BoundsException異常,因為整型數組c的長度為1,而程序試圖給c[42]賦值。
下面是運行在兩種不同情況下程序的輸出:
C:\>java MultiCatch
a = 0
Divide by 0: java.lang.ArithmeticException: / by zero After try/catch blocks.
C:\>java MultiCatch TestArg
a = 1
Array index oob: java.lang.ArrayIndexOutOfBoundsException After try/catch blocks.
當你用多catch語句時,記住異常子類必須在它們任何父類之前使用是很重要的。這是因為運用父類的catch語句將捕獲該類型及其所有子類類型的異常。這樣,如果子類在父類后面,子類將永遠不會到達。而且,Java中不能到達的代碼是一個錯誤。例如,考慮下面的程序:
1 /* This program contains an error. 2 A subclass must come before its superclass in a series of catch statements. If not,unreachable code will be created and acompile-time error will result. 3 */ 4 class SuperSubCatch { 5 public static void main(String args[]) { 6 try { 7 int a = 0; 8 int b = 42 / a; 9 } catch(Exception e) { 10 System.out.println("Generic Exception catch."); 11 } 12 /* This catch is never reached because 13 ArithmeticException is a subclass of Exception. */ 14 catch(ArithmeticException e) { // ERROR - unreachable 15 System.out.println("This is never reached."); 16 } 17 } 18 }
如果你試着編譯該程序,你會收到一個錯誤消息,該錯誤消息說明第二個catch語句不會到達,因為該異常已經被捕獲。因為ArithmeticException 是Exception的子類,第一個catch語句將處理所有的面向Exception的錯誤,包括ArithmeticException。這意味着第二個catch語句永遠不會執行。為修改程序,顛倒兩個catch語句的次序。
系列文章: