一.多层的异常捕获-1
先贴出代码:
1 public class CatchWho { 2 public static void main(String[] args) { 3 try { 4 try { 5 throw new ArrayIndexOutOfBoundsException(); 6 } 7 catch(ArrayIndexOutOfBoundsException e) { 8 System.out.println( "ArrayIndexOutOfBoundsException" + "/内层try-catch"); 9 } 10 11 throw new ArithmeticException(); 12 } 13 catch(ArithmeticException e) { 14 System.out.println("发生ArithmeticException"); 15 } 16 catch(ArrayIndexOutOfBoundsException e) { 17 System.out.println( "ArrayIndexOutOfBoundsException" + "/外层try-catch"); 18 } 19 } 20 }
运行结果:
ArrayIndexOutOfBoundsException/内层try-catch
发生ArithmeticException
然后我们在贴出一个修改之后的代码:
1 public class CatchWho2 { 2 public static void main(String[] args) { 3 try { 4 try { 5 throw new ArrayIndexOutOfBoundsException(); 6 } 7 catch(ArithmeticException e) { 8 System.out.println( "ArrayIndexOutOfBoundsException" + "/内层try-catch"); 9 } 10 throw new ArithmeticException(); 11 } 12 catch(ArithmeticException e) { 13 System.out.println("发生ArithmeticException"); 14 } 15 catch(ArrayIndexOutOfBoundsException e) { 16 System.out.println( "ArrayIndexOutOfBoundsException" + "/外层try-catch"); 17 } 18 } 19 }
再看编译出来的结果:
ArrayIndexOutOfBoundsException/外层try-catch
由两个运行程序的代码不同以及结果不同,我们可以简单的推断出一个小的猜测:当我们进行多层嵌套的异常抛出捕获时,一个异常的抛出,应当紧接着这个异常的捕获,否则抛出和捕获之间代码将没有办法运行。
结论:
可以在 try 语句后面添加任意数量的 catch 块。
如果保护代码中发生异常,异常被抛给第一个 catch 块。
如果抛出异常的数据类型与 ExceptionType1 匹配,它在这里就会被捕获。
如果不匹配,它会被传递给第二个 catch 块。
如此,直到异常被捕获或者通过所有的 catch 块。
二.多层的异常捕获-2
贴出代码:
1 package Javaexperiment04test01; 2 public class EmbededFinally { 3 public static void main(String args[]) { 4 5 int result; 6 7 try { 8 9 System.out.println("in Level 1"); 10 11 12 try { 13 14 System.out.println("in Level 2"); 15 // result=100/0; //Level 2 16 17 try { 18 19 System.out.println("in Level 3"); 20 21 result=100/0; //Level 3 22 23 } 24 25 catch (Exception e) { 26 27 System.out.println("Level 3:" + e.getClass().toString()); 28 29 } 30 31 32 finally { 33 34 System.out.println("In Level 3 finally"); 35 36 } 37 38 39 // result=100/0; //Level 2 40 41 42 } 43 44 catch (Exception e) { 45 46 System.out.println("Level 2:" + e.getClass().toString()); 47 48 } 49 finally { 50 51 System.out.println("In Level 2 finally"); 52 53 } 54 55 // result = 100 / 0; //level 1 56 57 } 58 59 catch (Exception e) { 60 61 System.out.println("Level 1:" + e.getClass().toString()); 62 63 } 64 65 finally { 66 67 System.out.println("In Level 1 finally"); 68 69 } 70 71 } 72 73 }
运行结果为:
in Level 1
in Level 2
in Level 3
Level 3:class java.lang.ArithmeticException
In Level 3 finally
In Level 2 finally
In Level 1 finally
而当我们在将代码中不同位置的// result=100/0;取消注释的时候我们会发现,代码运行的结果并不一样,在之前的地方取消注释我们会向上一个程序一样,捕获异常之前的代码都不会被运行,即使是finally语句。
总结:当有多层嵌套的finally时,异常在不同的层次抛出 ,在不同的位置抛出,可能会导致不同的finally语句块执行顺序。
三.finally语句块一定会执行吗?
先贴出代码:
1 package Javaexperiment04test01; 2 public class SystemExitAndFinally { 3 4 5 public static void main(String[] args) 6 { 7 8 try{ 9 10 11 System.out.println("in main"); 12 13 throw new Exception("Exception is thrown in main"); 14 15 //System.exit(0); 16 17 18 } 19 20 catch(Exception e) 21 22 { 23 24 System.out.println(e.getMessage()); 25 26 System.exit(0); 27 28 } 29 30 finally 31 32 { 33 34 System.out.println("in finally"); 35 36 } 37 38 } 39 40 41 }
运行结果:
in main
Exception is thrown in main
原因:在finally语句在被执行之前,程序已经被强制关闭,无法再次进行后续的编译。