1. 程式人生 > >finally return 執行關係 異常處理 c#

finally return 執行關係 異常處理 c#

Returnfinally執行關係簡述

除了函數出現system.exit(0)終止虛擬機器,finally中的程式碼一定執行,return語句會等待finally的執行;如果是值傳遞,finally中改變的值對trycatch塊中return返回的值無影響;如果是引用型別引數(地址傳遞或物件),finally中的值改變對return會產生影響。

如果是值型別,壓棧的就是經過複製的引數值,如果是引用型別,那麼進棧的只是一個引用,這也就是我們所熟悉的,傳遞值型別時,函式內修改引數值不會影響函式外,而引用型別的話則會影響。

下面就值傳遞而言,說明問題。變數拷貝問題。

提出問題:

    對於初學者來說,接觸異常類,老師通常會跟我們說異常處理分為try-catch

try-catch-finallytry-catch-ncatch-catch(Exception e)-[finally]等等結構,參考書中一般還會出現try-finally格式,對異常不做任何處理,直接執行。教科書上還會說finally{……}中的語句一定會執行。

    細心的讀者會發現return是退出語句,對後面程式碼短路,finally中程式碼一定會執行,這個不矛盾嗎?Catch中都return了,還會執行finally?結果是finally中程式碼是會執行的,但是執行的結果相當於區域性變數,是對之前變數的拷貝,改變的值不會對catchreturn值產生影響。

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語句的returncatch中的returnfinally語句,finally同樣不改變catchnum。返回值為1

3.如果finally中有return語句,程式會出現語法錯誤。

結論:

    在trycatch語句中,在執行return語句時,要返回的結果已經準備好了,就在此時,程式轉到finally執行了。在轉去之前,trycatch中先把要返回的結果存放到不同於i的區域性變數中去,執行完finally之後,在從中取出返回結果,因此,即使finally中對變數i進行了改變,但是不會影響返回結果。

    在我們知道了return語句並不全對下面的程式碼短路,改變了我們以往一直錯誤的觀念。但在出現異常處理時finally中的語句執行的結果不一定會對變數產生影響,但真的一定會執行嗎?答案是否定的,如果trycatch塊裡有System.exit(0) 終止當前正在執行的 Java 虛擬機器。finally裡面的程式碼是沒有機會執行的,這裡就不展開了。