有 return 的情况下 try catch finally 的执行顺序
论点
不管有没有出现异常,finally 块中代码都会执行;
当 try 和 catch 中有 return 时,finally 仍然会执行;
finally 是在 return 后面的表达式运算后执行的(此时并没有返回运算后的值,而是先把要返回的值保存起来,管 finally 中的代码怎么样,返回的值都不会改变,任然是之前保存的值),所以函数返回值是在 finally 执行前确定的;
finally 中最好不要包含 return,否则程序会提前退出,返回值不是 try 或 catch 中保存的返回值。
论据
情况 1:try{} catch(){}finally{} return;
显然程序按顺序执行。
情况 2:try{ return; }catch(){} finally{} return;
程序执行 try 块中 return 之前(包括 return 语句中的表达式运算)代码;
再执行 finally 块,最后执行 try 中 return;
finally 块之后的语句 return,因为程序在 try 中已经 return 所以不再执行。
情况 3:try{ } catch(){return;} finally{} return;
程序先执行 try,如果遇到异常执行 catch 块,
有异常:则执行 catch 中 return 之前(包括 return 语句中的表达式运算)代码,再执行 finally 语句中全部代码,最后执行 catch 块中 return. finally 之后也就是 4 处的代码不再执行。
无异常:执行完 try 再 finally 再 return.
情况 4:try{ return; }catch(){} finally{return;}
程序执行 try 块中 return 之前(包括 return 语句中的表达式运算)代码;
再执行 finally 块,因为 finally 块中有 return 所以提前退出。
情况 5:try{} catch(){return;}finally{return;}
程序执行 catch 块中 return 之前(包括 return 语句中的表达式运算)代码;
再执行 finally 块,因为 finally 块中有 return 所以提前退出。
情况 6:try{ return;}catch(){return;} finally{return;}
程序执行 try 块中 return 之前(包括 return 语句中的表达式运算)代码;
有异常:执行 catch 块中 return 之前(包括 return 语句中的表达式运算)代码;则再执行 finally 块,因为 finally 块中有 return 所以提前退出。
无异常:则再执行 finally 块,因为 finally 块中有 return 所以提前退出。
总结
任何执行 try 或者 catch 中的 return 语句之前,都会先执行 finally 语句,如果 finally 存在的话。如果 finally 中有 return 语句,那么程序就 return 了,所以 finally 中的 return 是一定会被 return 的,编译器把 finally 中的 return 实现为一个 warning。
版权声明: 本文为 InfoQ 作者【技术小生】的原创文章。
原文链接:【http://xie.infoq.cn/article/be817afbf8c08819d82e5512a】。文章转载请联系作者。
评论