多重catch块情况下的异常层次结构。
异常是在程序执行期间发生的错误(运行时错误)。当发生异常时,程序会突然终止,并且异常行之后的代码永远不会执行。
代码中的多个异常
当我们的代码可能产生多个异常,并且需要分别处理它们时,可以在单个try块上使用多个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("Array: "+Arrays.toString(arr)); System.out.println("Choose numerator and denominator (not 0) from this array (enter positions 0 to 5)"); int a = sc.nextInt(); int b = sc.nextInt(); try { int result = (arr[a])/(arr[b]); System.out.println("Result of "+arr[a]+"/"+arr[b]+": "+result); } catch(ArrayIndexOutOfBoundsException e) { System.out.println("Warning: You have chosen a position which is not in the array"); } catch(ArithmeticException e) { System.out.println("Warning: You cannot divide a number with 0"); } } }
输出1
Enter 3 integer values one by one: Array: [10, 20, 30, 2, 0, 8] Choose numerator and denominator(not 0) from this array (enter positions 0 to 5) 2 8 Warning: You have chosen a position which is not in the array
输出2
Enter 3 integer values one by one: Array: [10, 20, 30, 2, 0, 8] Choose numerator and denominator (not 0) from this array (enter positions 0 to 5) 1 4 Warning: You cannot divide a number with 0
异常顺序
如果对于单个try块,您有多个catch块,并且它们的异常类属于同一个层次结构,则需要确保捕获较高级别异常类的catch块最后放置。
否则,所有子类的异常都将在较高级别的catch块中处理,导致其余(catch)块无法访问,从而导致编译时异常。
示例
在以下Java程序中,单个try块包含4个catch块,依次处理IndexOutOfBoundsException、ArrayIndexOutOfBoundsException、Exception和ArithmeticException。
由于IndexOutOfBoundsException是ArrayIndexOutOfBoundsException的超类,因此与这两个类相关的异常都将在第一个catch块中处理,导致第二个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("Choose numerator and denominator (positions 0 to 5)"); int a = sc.nextInt(); int b = sc.nextInt(); try { int result = (arr[a])/(arr[b]); System.out.println("Result of "+arr[a]+"/"+arr[b]+": "+result); } catch(IndexOutOfBoundsException e) { System.out.println("Warning: position chosen is not in the array"); } catch(ArrayIndexOutOfBoundsException e) { e.printStackTrace(); } catch(Exception e) { e.printStackTrace(); } catch(ArithmeticException e) { System.out.println("Warning: You cannot divide a number with 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中编译上述代码,它会生成以下错误:
消息1 −
消息2 −
解决方案
要使上述代码正常工作,
捕获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("Choose numerator and denominator (enter positions 0 to 5)"); int a = sc.nextInt(); int b = sc.nextInt(); try { int result = (arr[a])/(arr[b]); System.out.println("Result of "+arr[a]+"/"+arr[b]+": "+result); } catch(ArrayIndexOutOfBoundsException e) { e.printStackTrace(); } catch(IndexOutOfBoundsException e) { System.out.println("Warning: You have chosen a position which is not in the array"); } catch(ArithmeticException e) { System.out.println("Warning: You cannot divide a number with 0"); } catch(Exception e) { e.printStackTrace(); } } }
广告