异常的执行流程
以下验证三个问题:
1.try catch语句抛出异常,finally语句也抛出异常,结果怎样?
2.try catch语句return和finally的执行顺序,先return还是先finally语句?
3.try catch语句和finall语句都return,最后return的是哪一个?
try catch语句抛出异常,finally语句也抛出异常,结果怎样?
有以下关系:
ExceptionA extends Exception
ExceptionB extends ExceptionA
ExceptionC extends ExceptionB
以下代码:
public class Test01 { public static void main(String[] args) throws Exception,ExceptionA,ExceptionB{ try{ System.out.println("抛ExceptionC异常"); throw new ExceptionC("ExceptionC"); }catch(ExceptionB e){ System.out.println("抛ExceptionB异常"); throw new ExceptionB("ExceptionB"); }catch(ExceptionA e){ System.out.println("抛ExceptionA异常"); throw new ExceptionA("ExceptionA"); }finally{ System.out.println("抛ExceptionFinally异常"); throw new Exception("ExceptionFinally"); } } } 输出如下: 抛ExceptionC异常 抛ExceptionB异常 抛ExceptionFinally异常 Exception in thread "main" java.lang.Exception: ExceptionFinally at Test01.main(Test01.java:16)
由结果可以知道,虽然第一个catch捕获到try语句的异常,但没有抛出成功,而是抛出了finally的异常,finally里面抛出异常会提前结束程序。
值得注意的是第一个catch捕获到异常后,抛出ExceptionB异常,但没有被第二个catch捕获,因为同一个try只会根据顺序catch一次。
try catch语句return和finally的执行顺序,先return还是先finally语句?
代码如下:
public class Test01 { public static void main(String[] args) { System.out.println(test3()); } public static int test3(){ int i=0; try{ i++; return i; }catch(Exception e){ i++; return i; }finally{ i++; } } }
执行顺序:
1) 执行try语句,i=1,将要返回的1先保存,等执行完finally再返回这个值
2)执行finally,i=2,接着执行上面的return语句,将1返回
注:如果return的是引用类型,那么finally对该变量的修改可能会影响返回值,比如对数组元素的修改,return的依然是原来的数组,但是内容可能已经变了。
try catch语句和finall语句都return,最后return的是哪一个?
代码如下:
public class Test01 { public static void main(String[] args) { System.out.println(test2()); } public static int test2(){ int i=0; try{ i++; return i; }catch(Exception e){ return -1; }finally{ i++; return i; } } } 输出: 2
执行顺序如下:
1) 执行try语句,i=1,将要返回的1先保存,等执行完finally再返回这个值
2)执行finally,i=2,返回2,此时程序提前结束,上面的1无法被返回
总结
1、不管有木有出现异常,finally块中代码都会执行;
2、当try和catch中有return或throw时,finally仍然会执行;
3、finally是在return后面的表达式运算后执行的(此时并没有返回运算后的值,而是先把要返回的值保存起来,管finally中的代码怎么样,返回的值都不会改变,任然是之前保存的值),所以函数返回值是在finally执行前确定的;
4、finally中最好不要包含return,否则程序会提前退出,返回值不是try或catch中保存的返回值。
5、finally中最好不要包含throw,否则程序会提前退出,抛出的异常不是try或catch中的抛出的,而是finally抛出的。