动手动脑五
import javax.swing.*; class AboutException { public static void main(String[] a) { //int i=1, j=0, k; //k=i/j; try { int i=1, j=0, k; k = i/j; // Causes division-by-zero exception //throw new Exception("Hello.Exception!"); } catch ( ArithmeticException e) { System.out.println("被0除. "+ e.getMessage()); } catch (Exception e) { if (e instanceof ArithmeticException) System.out.println("被0除"); else { System.out.println(e.getMessage()); } } finally { JOptionPane.showConfirmDialog(null,"OK"); } } }
程序分析:
try语句中运行发生异常,跳转到catch语句中执行System.out.println("被0除. "+ e.getMessage());语句,所以输出如上。无论是否发生异常最后执行了finally语句,弹出上述页面防止程序崩溃。
public class CatchWho { public static void main(String[] args) { try { try { throw new ArrayIndexOutOfBoundsException(); } catch(ArrayIndexOutOfBoundsException e) { System.out.println( "ArrayIndexOutOfBoundsException" + "/内层try-catch"); } throw new ArithmeticException(); } catch(ArithmeticException e) { System.out.println("发生ArithmeticException"); } catch(ArrayIndexOutOfBoundsException e) { System.out.println( "ArrayIndexOutOfBoundsException" + "/外层try-catch"); } } }
我们根据程序运行的结果可以知道程序实际上式执行了第8行与第14行的输出语句,而没有执行第17行。
public class CatchWho2 { public static void main(String[] args) { try { try { throw new ArrayIndexOutOfBoundsException(); } catch(ArithmeticException e) { System.out.println( "ArrayIndexOutOfBoundsException" + "/内层try-catch"); } throw new ArithmeticException(); } catch(ArithmeticException e) { System.out.println("发生ArithmeticException"); } catch(ArrayIndexOutOfBoundsException e) { System.out.println( "ArrayIndexOutOfBoundsException" + "/外层try-catch"); } } }
运行后我们根据程序运行的结果可以知道程序实际上式执行了第16行的输出语句,而没有执行第8行与第13行。
通过上述两个实例,我们可以总结出java多层嵌套异常处理的基本流程:
try语句可以被嵌套。也就是说,一个try语句可以在另一个try块内部。每次进入try语句,异常的前后关系都会被推入堆栈。如果一个内部的try语句不含特殊异常的catch处理程序,堆栈将弹出,下一个try语句的catch处理程序将检查是否与之匹配。这个过程将继续直到一个catch语句匹配成功,或者是直到所有的嵌套try语句被检查耗尽。如果没有catch语句匹配,Java的运行时系统将处理这个异常。
public class EmbededFinally { public static void main(String args[]) { int result; try { System.out.println("in Level 1"); try { System.out.println("in Level 2"); // result=100/0; //Level 2 try { System.out.println("in Level 3"); result=100/0; //Level 3 } catch (Exception e) { System.out.println("Level 3:" + e.getClass().toString()); } finally { System.out.println("In Level 3 finally"); } // result=100/0; //Level 2 } catch (Exception e) { System.out.println("Level 2:" + e.getClass().toString()); } finally { System.out.println("In Level 2 finally"); } // result = 100 / 0; //level 1 } catch (Exception e) { System.out.println("Level 1:" + e.getClass().toString()); } finally { . System.out.println("In Level 1 finally"); } } }
当有多层嵌套的finally时,异常在不同层次抛出,在不同的位置抛出,可能会导致不同的finally语句块执行顺序
public class SystemExitAndFinally { public static void main(String[] args) { try{ System.out.println("in main"); throw new Exception("Exception is thrown in main"); //System.exit(0); } catch(Exception e) { System.out.println(e.getMessage()); System.exit(0); } finally { System.out.println("in finally"); } } }
如果finally块中的代码过多会导致字节码条数”膨胀”,因为finally中的字节码会被”复制”到try块和所有的catch块中,出异常了。System.out.println("F")不在finally里。而只有finally里的语句才会不论如何都会执行。