try..catch..finally执行顺序return

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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。
分析:
	在try语句中,在执行return语句时,要返回的结果已经准备好了,就在此时,程序转到finally执行了。
在转去之前,try中先把要返回的结果存放到不同于x的局部变量中去,执行完finally之后,在从中取出返回结果,
因此,即使finally中对变量x进行了改变,但是不会影响返回结果。
它应该使用栈保存返回值。


C#中 finally 代码块里面不能写 return 语句   会报错 控制不能离开finally子句主体


 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     }

 



以上是关于try..catch..finally执行顺序return的主要内容,如果未能解决你的问题,请参考以下文章

异常处理 try...catch...finally 执行顺序, 以及对返回值得影响

关于try catch finally的执行顺序解释

Java try/catch/finally内部执行顺序&外部语句何种情况下执行

try..catch..finally执行顺序return

try catch finally 中 returne的执行顺序

try...catch...finally执行顺序