在本教程中,我們將借助示例學(xué)習(xí)如何在Java中處理多個異常。
在Java 7之前,即使存在代碼冗余,我們也必須針對不同類型的異常編寫多個異常處理代碼。
讓我們舉個實例。
class Main { public static void main(String[] args) { try { int array[] = new int[10]; array[10] = 30 / 0; } catch (ArithmeticException e) { System.out.println(e.getMessage()); } catch (ArrayIndexOutOfBoundsException e) { System.out.println(e.getMessage()); } } }
輸出結(jié)果
/ by zero
在此的示例可能會發(fā)生兩個異常:
ArithmeticException - 因為我們試圖將數(shù)字除以0。
ArrayIndexOutOfBoundsException - 因為我們已經(jīng)聲明了一個新的整數(shù)數(shù)組,數(shù)組邊界為0到9,并且我們試圖為索引10分配一個值。
我們在兩個catch塊中都打印出異常消息,即重復(fù)代碼。
賦值運算符(=)的關(guān)聯(lián)性是從右到左,因此首先將ArithmeticException與消息 / by zero起拋出。
在Java SE 7和更高版本中,我們現(xiàn)在可以在單個catch塊中捕獲多種類型的異常。
可以由catch塊處理的每種異常類型都使用豎線(|)分隔。
其語法為:
try { // code } catch (ExceptionType1 | Exceptiontype2 ex) { // catch block }
class Main { public static void main(String[] args) { try { int array[] = new int[10]; array[10] = 30 / 0; } catch (ArithmeticException | ArrayIndexOutOfBoundsException e) { System.out.println(e.getMessage()); } } }
輸出結(jié)果
/ by zero
在單個catch塊中捕獲多個異常,可以減少代碼重復(fù)并提高效率。
編譯該程序時生成的字節(jié)碼將比具有多個catch塊的程序小,因為沒有代碼冗余。
注意:如果一個catch塊處理多個異常,則catch參數(shù)為隱式final。這意味著我們不能分配任何值來捕獲參數(shù)。
當(dāng)在單個catch塊中捕獲多個異常時,該規(guī)則將泛化為專門化規(guī)則。
這意味著,如果catch塊中存在異常的層次結(jié)構(gòu),我們只能捕獲基本異常,而不能捕獲多個專門的異常。
讓我們舉個實例。
class Main { public static void main(String[] args) { try { int array[] = new int[10]; array[10] = 30 / 0; } catch (Exception e) { System.out.println(e.getMessage()); } } }
輸出結(jié)果
/ by zero
我們知道所有異常類都是Exception類的子類。因此,我們不必捕獲多個專門的異常,而只需捕獲Exception類。
如果已經(jīng)在catch塊中指定了基本異常類,則不要在同catch一塊中使用子異常類。否則,我們會得到一個編譯錯誤。
讓我們舉個實例。
class Main { public static void main(String[] args) { try { int array[] = new int[10]; array[10] = 30 / 0; } catch (Exception | ArithmeticException | ArrayIndexOutOfBoundsException e) { System.out.println(e.getMessage()); } } }
輸出結(jié)果
Main.java:6: error: Alternatives in a multi-catch statement cannot be related by subclassing
在此示例中,ArithmeticException和ArrayIndexOutOfBoundsException都是Exception類的子類。 因此,我們拋出一個編譯錯誤。