finally return 執行關係 異常處理 c#
Return、finally執行關係簡述
除了函數出現system.exit(0)終止虛擬機器,finally中的程式碼一定執行,return語句會等待finally的執行;如果是值傳遞,finally中改變的值對try或catch塊中return返回的值無影響;如果是引用型別引數(地址傳遞或物件),finally中的值改變對return會產生影響。
如果是值型別,壓棧的就是經過複製的引數值,如果是引用型別,那麼進棧的只是一個引用,這也就是我們所熟悉的,傳遞值型別時,函式內修改引數值不會影響函式外,而引用型別的話則會影響。
下面就值傳遞而言,說明問題。變數拷貝問題。
提出問題:
對於初學者來說,接觸異常類,老師通常會跟我們說異常處理分為try-catch
細心的讀者會發現return是退出語句,對後面程式碼短路,finally中程式碼一定會執行,這個不矛盾嗎?Catch中都return了,還會執行finally?結果是finally中程式碼是會執行的,但是執行的結果相當於區域性變數,是對之前變數的拷貝,改變的值不會對catch中return值產生影響。
finally_return例項
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace finallyReturn { class Program { static void Main(string[] args) { int num= Test_Finally_Return.Test(); Console.WriteLine("num={0}",num); Console.ReadKey(); } } class Test_Finally_Return { public static int Test() { int num =0; try { num = 1; throw new Exception("手動控制丟擲異常"); //若將throw註釋掉,通過try中return返回,即正常執行時會不會執行finally,答案是會執行,但函式返回-1 //return -1; } catch (Exception e) { Console.WriteLine(e.Message); return num; //輸出是多少??思考??輸出num=1;相信很多人會認為返回2,這裡面相當於是變數copy,finally中的變數改變對return值無影響。 } finally { num++;//若果執行,那麼返回應該是多少????執行了,num=2 Console.WriteLine("我在Finally中num={0}",num); //return 5;//finall中不能包含return語句,否則會報錯 } } } }
例項結果解釋:
1.沒有異常時,走try語句的return,走finally語句,但finally中不影響num值,返回值為-1。
2.有異常時,不走try語句的return,走catch中的return,走finally語句,finally同樣不改變catch中num值。返回值為1。
3.如果finally中有return語句,程式會出現語法錯誤。
結論:
在try或catch語句中,在執行return語句時,要返回的結果已經準備好了,就在此時,程式轉到finally執行了。在轉去之前,try或catch中先把要返回的結果存放到不同於i的區域性變數中去,執行完finally之後,在從中取出返回結果,因此,即使finally中對變數i進行了改變,但是不會影響返回結果。
在我們知道了return語句並不全對下面的程式碼短路,改變了我們以往一直錯誤的觀念。但在出現異常處理時finally中的語句執行的結果不一定會對變數產生影響,但真的一定會執行嗎?答案是否定的,如果try或catch塊裡有System.exit(0) 終止當前正在執行的 Java 虛擬機器。finally裡面的程式碼是沒有機會執行的,這裡就不展開了。