多个 catch 块情况下的异常层次结构。
异常是程序执行过程中发生的问题(运行时错误)。发生异常时,程序会突然终止,并且生成异常的行之后的代码永远不会执行。
代码中的多个异常
每当我们的代码可能生成多个异常时,如果您需要专门处理它们,您可以在一次尝试中使用多个 catch 块。
try{ //code } catch(Exception1 ex1) { // } catch(Exception2 ex2) { // }
示例
import java.util.Arrays; import java.util.Scanner; public class MultipleCatchBlocks { public static void main(String [] args) { Scanner sc = new Scanner(System.in); int[] arr = {10, 20, 30, 2, 0, 8}; System.out.println("数组:"+Arrays.toString(arr)); System.out.println("从此数组中选择分子和分母(非 0)(输入位置 0 到 5)"); int a = sc.nextInt(); int b = sc.nextInt(); try { int result = (arr[a])/(arr[b]); System.out.println(""+arr[a]+"/"+arr[b]+"的结果: "+result); } catch(ArrayIndexOutOfBoundsException e) { System.out.println("警告: 您选择的位置不在数组中"); } catch(ArithmeticException e) { System.out.println("警告:不能用 0 除以数字"); } } }
输出 1
逐个输入 3 个整数值: 数组:[10, 20, 30, 2, 0, 8] 从此数组中选择分子和分母(非 0)(输入位置 0 到 5) 2 8 警告:您选择的位置不在数组中
输出 2
逐个输入 3 个整数值: 数组:[10, 20, 30, 2, 0, 8] 从此数组中选择分子和分母(非 0)(输入位置 0 到 5) 1 4 警告:您不能用 0 除以数字
顺序异常
如果单个 try 有多个 catch 块,并且它们的异常类属于同一层次结构,则需要确保捕获更高级别异常类的 catch 块在 catch 块顺序中位于最后。
如果不是,则子类的所有异常将在更高级别的 catch 块中处理,从而使其余(catch)块无法访问,从而导致编译时异常。
示例
在下面的 Java 程序中,单个 try 块包含 4 个 catch 块,以相同的顺序处理 IndexOutOfBoundsException、ArrayIndexOutOfBoundsException、Exception 和 ArithmeticException。
由于 IndexOutOfBoundsException 是 ArrayIndexOutOfBoundsException 的超类,因此与这两个类相关的异常在第一个 catch 块中处理,使得后一个块无法访问。
由于Exception 是所有异常类的超类,如果将捕获该异常的 catch 块放置在捕获任何其他异常的 catch 块之前,则所有异常都将在 Exception 块本身中处理,从而使其余块无法访问。
import java.util.Arrays; import java.util.Scanner; public class ExceptionHierarchy { public static void main(String [] args) { Scanner sc = new Scanner(System.in); int[] arr = {10, 20, 30, 2, 0, 8}; System.out.println("Array: "+Arrays.toString(arr)); System.out.println("选择分子和分母(位置 0 到 5)"); int a = sc.nextInt(); int b = sc.nextInt(); try { int result = (arr[a])/(arr[b]); System.out.println(""+arr[a]+"/"+arr[b]+"的结果: "+result); } catch(IndexOutOfBoundsException e) { System.out.println("警告: 所选位置不在数组中"); } catch(ArrayIndexOutOfBoundsException e) { e.printStackTrace(); } catch(Exception e) { e.printStackTrace(); } catch(ArithmeticException e) { System.out.println("警告:您不能用 0 除以数字"); } } }
输出
编译时异常
ExceptionHierarchy.java:16: error: exception ArrayIndexOutOfBoundsException has already been caught }catch(ArrayIndexOutOfBoundsException e) { ^ ExceptionHierarchy.java:20: error: exception ArithmeticException has already been caught }catch(ArithmeticException e) { ^ 2 errors
如果在 eclipse 中编译上述代码,则会生成以下错误 −
Message1 −
Message2 −
解决方案
要使上述代码工作,
捕获 IndexOutOfBoundsException 的 catch 块应放在捕获 ArrayIndexOutOfBoundsException 的 catch 块之后。
捕获 Exception 对象的 catch 块应按照 catch 块顺序放在最后。
示例
import java.util.Arrays; import java.util.Scanner; public class ExceptionHierarchy { public static void main(String [] args) { Scanner sc = new Scanner(System.in); int[] arr = {10, 20, 30, 2, 0, 8}; System.out.println("Array: "+Arrays.toString(arr)); System.out.println("选择分子和分母(输入位置 0 到 5)"); int a = sc.nextInt(); int b = sc.nextInt(); try { int result = (arr[a])/(arr[b]); System.out.println(""+arr[a]+"/"+arr[b]+"的结果: "+result); } catch(ArrayIndexOutOfBoundsException e) { e.printStackTrace(); } catch(IndexOutOfBoundsException e) { System.out.println("警告: 您选择的位置不在数组中"); } catch(ArithmeticException e) { System.out.println("警告:不能用 0 除以某个数字"); } catch(Exception e) { e.printStackTrace(); } } }