try..catch..finally执行顺序return
结论:
1、不管有木有出现异常,finally块中代码都会执行;
2、当try和catch中有return时,finally仍然会执行;
3、finally是在return后面的表达式运算后执行的(此时并没有返回运算后的值,而是先把要返回的值保存起来,管finally中的代码怎么样,返回的值都不会改变,任然是之前保存的值),所以函数返回值是在finally执行前确定的;
4、finally中最好不要包含return,否则程序会提前退出,返回值不是try或catch中保存的返回值。
不管是执行try还是catch,如果所执行的语句中(try和catch中的return只有一个会执行,如果被catch了,肯定是执行catch语句中的return;如果没有被catch,那肯定是执行try中的return。这里假设它们中有return,如果没有return,肯定会执行finally后面的语句)有return语句,则finally之后的语句就不执行(finally里面的语句肯定还是执行啦);如果是执行try或catch中的语句块没有return语句,则finally后面的语句还是会执行的。
举例:
情况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。
下面是个测试程序 public class FinallyTest { public static void main(String[] args) { System.out.println(new FinallyTest().test());; } static int test() { int x = 1; try { x++; return x; } finally { ++x; } } } 结果是2。
分析:
1 class Program 2 { 3 static int test() 4 { 5 int x = 1; 6 try 7 { 8 x++; 9 return x; 10 } 11 finally 12 { 13 ++x; 14 // return 8; finally 代码块里面不能写 return 语句 控制不能离开finally子句主体 15 // finally总会被执行的 如果在finally里面执行return,就会把后面代码遗漏执行。 16 } 17 } 18 19 20 static void Main(string[] args) 21 { 22 Console.WriteLine(test()); 23 } 24 //在try语句中,在执行return语句时,要返回的结果已经准备好了,就在此时,程序转到finally执行了。 25 //在转去之前,try中先把要返回的结果存放到不同于x的局部变量中去,执行完finally之后,在从中取出返回结果, 26 //因此,即使finally中对变量x进行了改变,但是不会影响返回结果。 27 //它应该使用栈保存返回值。 28 //如果finally存在的话。 任何执行try 或者catch中的return语句之前,都会先执行finally语句 29 30 // C#有很多不允许: 31 //比如不允许 = 出现在bool表达式里面: 32 //C++ if (i = 3) // 允许 33 //C# if (i = 3) //不允许 34 //不允许没有break,比如 35 //C++ case 1: a = 2; case 2 : b = 3; //允许 36 //C# case 1: a = 2; case 2 : b = 3; //不允许 37 //C# case 1: case 2 : b = 3; break; //允许 38 //C#不允许函数没有返回值,而声明中有,比如 39 //int func() { return; } //不允许 40 41 //C#去掉了容易出错的语法。 42 43 // try 44 //{ 45 // FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read); 46 // StreamReader sr = new StreamReader(fs); 47 // sr.BaseStream.Seek(0, SeekOrigin.Begin); 48 // Console.WriteLine("read"); 49 // string temp; 50 // while ((temp = sr.ReadLine()) != null) 51 // { 52 // result.Add(temp); 53 // } 54 //} 55 //catch (Exception ex) 56 //{ 57 // Console.WriteLine(ex.Message); 58 //} 59 //finally 60 //{ 61 // return result; 62 //} 63 64 65 66 // try 67 //{ 68 // FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read); 69 // StreamReader sr = new StreamReader(fs); 70 // sr.BaseStream.Seek(0, SeekOrigin.Begin); 71 // Console.WriteLine("read"); 72 // string temp; 73 // while ((temp = sr.ReadLine()) != null) 74 // { 75 // result.Add(temp); 76 // } 77 //} 78 //catch (Exception ex) 79 //{ 80 // Console.WriteLine(ex.Message); 81 //} 82 83 //return result; 84 85 //第二种结构更简洁、清晰. 86 87 //frinally一般只做一些清理工作 88 //finally是不管前面如何都会执行的 善后处理 89 90 91 }
相关文章
- Python异常捕捉try except else finally有return时执行顺序探究
- gulp顺序执行任务
- EXEC执行动态的SQL语句
- 【MATLAB教程案例93】在MATLAB中通过mex将C语言转化为matlab可执行的mexw64文件
- Jmeter元件的作用域与执行顺序
- postgreSQL timing 查看SQL执行时间
- springMVC执行流程详解
- 【分析】浅谈C#中Control的Invoke与BeginInvoke在主副线程中的执行顺序和区别(SamWang)
- 浅谈C#中Control的Invoke与BeginInvoke在主副线程中的执行顺序和区别
- 【问题-vue-vuetify】vue执行npm run serve后浏览器端口:5000显示Cannot GET /
- mysql 的编写顺序和执行顺序
- Spring Boot中使用@Async实现异步调用,加速任务的执行!
- Java子父类继承情况下构造函数/代码块/静态代码块执行顺序
- SQL Server SQL语句执行顺序
- 用arthas的watch方法观察执行方法的输入输出
- 静态变量、静态块、成员变量、构造函数在类实例化时执行顺序
- 基于ABP的应用执行Update-Database出现异常的解决办法
- SQL Server 执行计划利用统计信息对数据行的预估原理二(为什么复合索引列顺序会影响到执行计划对数据行的预估)
- pipeline的添加顺序和执行顺序
- Linux 文件的读写执行权限的说明
- 所以 if a 代表如果a有值的时候执行的内容,有值才能执行是True if not a 代表 a无值是空的时候执行的内容 not False 是True才能执行 代表空值的时候执行
- PIM-DM协议内核触发机制及协议执行机制记录
- 应用Druid监控SQL语句的执行情况--转载
- @PostConstruct、Servlet的init()方法、构造器、spring的autowired的执行顺序
- [Mysql] SQL的书写顺序与执行顺序