今天看一個Java SSH的面試題,題目大概意思是:try、catch中存在return語句,還會執行finally塊嗎?若是執行,是return先執行仍是finally先執行?若是有多個return語句,結果如何?面試
看了之後我還真犯嘀咕,作了軟件開發這些年,還沒認真思考過則個問題,因而趕忙寫個測試測試代碼以下:app
1 class Program 2 { 3 public static int a = 0; 4 static void Main(string[] args) 5 { 6 var result = GetValue(); 7 } 8 9 public static int GetValue() 10 { 11 try 12 { 13 a = 2; 14 throw new Exception(); 15 } 16 catch (Exception ex) 17 { 18 a = 3; 19 return a; 20 a = 4; 21 } 22 finally 23 { 24 a = 5; 25 } 26 } 27 }
爲了探究個明白,使用ILSpy工具查看IL代碼, GetValue()的IL代碼以下:ide
1 .method public hidebysig static 2 int32 GetValue () cil managed 3 { 4 // Method begins at RVA 0x2064 5 // Code size 42 (0x2a) 6 .maxstack 1 7 .locals init ( 8 [0] class [mscorlib]System.Exception ex,//定義Exception類型變量 ex 9 [1] int32 CS$1$0000 //定義int32類型變量 CS$1$000 10 ) 11 12 IL_0000: nop //No Operation 沒有任何操做 13 .try 14 { 15 .try 16 { 17 IL_0001: nop 18 IL_0002: ldc.i4.2 //把int32 類型的數據2 推入計算堆棧上 19 IL_0003: stsfld int32 ConsoleApplication1.Program::a //用計算堆棧的值替換靜態字段a的值 20 IL_0008: newobj instance void [mscorlib]System.Exception::.ctor() //實例化Exception對象,並將對象推入到計算堆棧上 21 IL_000d: throw //引起當前位於計算堆棧上的異常對象 22 } // end .try 23 catch [mscorlib]System.Exception 24 { 25 IL_000e: stloc.0 //從計算堆棧的頂部彈出當前值(Exception對象)並將其存儲到索引 0 處的局部變量列表中 26 IL_000f: nop 27 IL_0010: ldc.i4.3 //把整數類型3推入計算堆棧上 28 IL_0011: stsfld int32 ConsoleApplication1.Program::a //用計算堆棧的值置換靜態變量a的值 29 IL_0016: ldsfld int32 ConsoleApplication1.Program::a //將靜態字段a的值推入計算堆棧上 30 IL_001b: stloc.1 //從計算堆棧的頂部彈出當前值,並將其存儲到索引 1 處的局部變量列表中 31 IL_001c: leave.s IL_0027 //退出受保護的代碼區域,無條件將控制轉移到目標指令 [ leave.s 指令清空計算堆棧並確保執行周圍適當的 finally 塊。] 32 } // end handler 33 } // end .try 34 finally 35 { 36 IL_001e: nop 37 IL_001f: ldc.i4.5 //把整數5推入計算堆棧上 38 IL_0020: stsfld int32 ConsoleApplication1.Program::a //用計算對象韓的值置換靜態變量a的值 39 IL_0025: nop 40 IL_0026: endfinally //將控制從異常塊的 fault 或 finally 子句轉移回公共語言結構 (CLI) 異常處理程序。 41 } // end handler 42 43 IL_0027: nop 44 IL_0028: ldloc.1 //將索引 1 處的局部變量加載到計算堆棧上 45 IL_0029: ret //從當前方法返回,並將返回值(若是存在)從調用方的計算堆棧推送到被調用方的計算堆棧上 46 } // end of method Program::GetValue
經過IL代碼和相關的註釋,基本能夠看出他們的執行流程,猜想出這個方法返回的結果以及靜態變量a最後的值是多少。工具
最後GetValue()方法返回的結果是3;靜態變量a的值是5;測試
可是 「IL_001c: leave.s IL_0027 」 leave.s 還沒看明白怎麼回事?有相關熟悉的人,請指點,謝謝!ui
另外問題提到:有多個return的狀況,返回哪一個return的結果? 我試了一下,沒有發現容許執行屢次return的可能!若是有請不吝指出!lua