try-catch-finally语句的执行顺序是怎样的?,简述try-catch-finally的执行过程
00-1010简介:try块中有returncatch块,returntry块和finally块,returntry块和finally块中有return summaries。
00-1010 Java异常处理,大家都知道try、catch、finally的执行顺序是有顺序的,这里就不废话了。但是,当try、catch和finally与return一起添加时,会出现几种不同的情况。下面我们分别来解释一下。也可以跳到最后直接看摘要。
00-1010这里列举了五种情况,将一一说明。
00-1010 try { system . out . println( try块代码运行);返回0;} catch(exception e){ system . out . println( catch块代码运行);} finally { system . out . println( finally block代码运行);}返回1;输出结果:
Try块代码运行最终块代码运行并最终返回33600。
执行流程:
在try块中执行return前的代码(包括return语句中的表达式操作)-执行finally块-在try中执行return。
结论:
当try中有return时,首先执行return之前的代码,然后执行暂时保存需要return的信息,然后执行finally中的代码,最后通过return返回之前保存的信息。语句在finally块之后返回,不再执行,因为程序在try中已经通过了已经return,方法的执行已经结束。
但是有一点要注意,如果返回值是引用类型呢?再看另一个例子:
list integer list=new ArrayList();尝试{ list . add(0);system . out . println( try : list);退货单;} catch(异常e){ list . add(1);system . out . println( catch : list);}最后{ list . add(2);system . out . println( finally : list);}返回列表;输出:
尝试: [0]最终3360 [0,2]最终返回: [0,2]
看完这个例子,你可能会发现一个问题。刚才提到return的时候,会临时保存需要返回的信息,不受finally块中代码的影响。但是在这里,链表中存储的不是变量本身,而是变量的地址,所以当最终通过地址改变变量时,还是会影响方法的返回值。
00-1010 try { system . out . println( try块代码运行);//int x=1/0;} catch(exception e){ system . out . println( catch块代码运行);返回0;} finally { system . out . println( finally block代码运行);}返回1;输出结果:
//无异常try块代码运行最终块代码运行最终返回33601//有异常try块代码运行catch块代码运行最终块代码运行最终返回33600。
执行流程:
程序首先执行try,如果遇到异常,则执行catch块。
异常:在catch中执行return之前的代码(包括return语句中的表达式操作),然后执行finally语句中的所有代码,最后在catch块中执行return,但不会执行finally之后的return。
没有例外:尝试,最后,然后返回。
结论:
Return in catch类似于try。如果发生异常,catch块中的return信息会被临时保存,然后执行finally中的代码,最后通过return返回之前保存的信息。
目录
h2>
try{ System.out.println("try块代码运行了"); return 0;}catch(Exception e){ System.out.println("catch块代码运行了");}finally { System.out.println("finally块代码运行了"); return 1;}
输出结果:
try块代码运行了finally块代码运行了最终返回:1
执行流程:
程序执行try块中return之前(包括return语句中的表达式运算)代码,再执行finally块。因为finally块中有return所以提前退出,而不再执行try中的return。
备注:
这种写法是可以编译通过的,但是编译器会给予警告。我们一般不在finally块中写return语句,这里只是刻意演示了一下效果。
catch块和finally块中有return
try{ System.out.println("try块代码运行了"); //int x = 1 / 0 ;}catch(Exception e){ System.out.println("catch块代码运行了"); return 0;}finally { System.out.println("finally块代码运行了"); return 1;}
输出结果:
//无异常try块代码运行了finally块代码运行了最终返回:1
//有异常try块代码运行了catch块代码运行了finally块代码运行了最终返回:1
执行流程:
无异常:执行try后跳过catch执行finally,得到finally的返回值1;
有异常:程序执行catch块中return之前(包括return语句中的表达式运算)代码,再执行finally块。因为finally块中有return所以提前退出,而不再执行catch中的return。
try块、catch块和finally块中都有return
try{ System.out.println("try块代码运行了"); //int x = 1 / 0 ; return 0;}catch(Exception e){ System.out.println("catch块代码运行了"); return 1;}finally { System.out.println("finally块代码运行了"); return 2;}
输出结果:
//无异常try块代码运行了finally块代码运行了
最终返回:2//有异常try块代码运行了catch块代码运行了finally块代码运行了
最终返回:2
执行流程:
程序执行try块中return之前(包括return语句中的表达式运算)代码,
无异常:然后再执行finally块,因为finally块中有return所以提前退出;
有异常:执行catch块中return之前(包括return语句中的表达式运算)代码,再执行finally块。因为finally块中有return所以提前退出。
结论:
得到finally中的返回值3。
总结
无论catch是否捕获异常,finally语句块都是要被执行的。
当try块或catch块return一个值,那么finally块中的代码会在执行return后,返回之前执行。(此时并没有返回运算后的值,而是把要返回的值暂时保存起来)。
finally中如果包含return,那么程序将在这里返回,而不是通过try或catch中的return返回,返回值就不是try或catch中保存的返回值了。会直接在finally中结束方法的执行,导致try、catch中的return失效。
当try或catch,finally中都包含return的时候,要注意返回值的类型。finally修改的基本类型是不影响返回结果的,修改list、map、自定义类等引用类型时,是影响返回结果的。
编译器会对finally中的return给予警告,因为从finally中返回可能会导致异常丢失 。如:
try{ try { throw new RuntimeException("来自try块中的异常") ; }finally{ return; }}catch (Exception e){ e.printStackTrace(System.out) ;}
这里无法捕获 我们自定义的运行时异常。
又如:
try{ try { throw new RuntimeException("来自try块中的异常") ; }finally{ throw new RuntimeException("来自finally块中的异常") ; }}catch (Exception e){ e.printStackTrace(System.out) ;}
这里会丢失 第一个异常。
到此这篇关于try-catch-finally执行顺序你知道吗的文章就介绍到这了,更多相关try-catch-finally执行顺序内容请搜索盛行IT以前的文章或继续浏览下面的相关文章希望大家以后多多支持盛行IT!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。