日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

一道异常处理执行顺序面试题的简单分析

發布時間:2025/5/22 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 一道异常处理执行顺序面试题的简单分析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
異常處理,我們寫的代碼里經常會用到:try{}catch{}finally{}。可是大家真的了解它嗎?

下面的代碼,運行結果是什么?大家猜一下:

View Code? static?class?Program
????{

????????static?void?Main(string[]?args)
????????{
????????????Console.WriteLine(Program.MethodC());
????????????Program.MethodB();
????????????Console.ReadLine();
????????}

????????static?void?MethodA()
????????{
????????????try
????????????{
????????????????throw?new?NullReferenceException();
????????????}
????????????catch?(IndexOutOfRangeException)
????????????{
????????????????throw;
????????????}
????????????finally
????????????{
????????????????Console.WriteLine("MethodA?finally");
????????????}
????????}

????????static?void?MethodB()
????????{
????????????try
????????????{
????????????????MethodA();
????????????}
????????????catch?(NullReferenceException)
????????????{
????????????????Console.WriteLine("MethodB?catch");
????????????}
????????????finally
????????????{
????????????????Console.WriteLine("MethodB?finally");
????????????}
????????}

????????static?int?i?=?1;
????????static?int?MethodC()
????????{
????????????try
????????????{
????????????????Console.WriteLine("MethodC?try");
????????????????return?i;
????????????}
????????????finally
????????????{
????????????????i?=?2;
????????????????Console.WriteLine("MethodC?finally");
????????????????Console.WriteLine("MethodC:"+i);
????????????}
????????}

?下面給出運行結果:

View Code? MethodC?try
MethodC?finally
MethodC:2
1
MethodA?finally
MethodB?catch
MethodB?finally

?看上面的運行結果,語句:Console.WriteLine(Program.MethodC())的輸出為:

MethodC?try
MethodC?finally
MethodC:2
1

MethodC方法,主要考察的有二點,一是finally語句和return語句執行的先后順序,二是finally語句是否可以改變return語句中返回的值。
第一點大家都知道,return前finally總是會執行,第二點就有些模糊了,運行結果也跟最初自己猜的不同。我們看一下MethodC方法生成的IL代碼:

.method?private?hidebysig?static?int32??MethodC()?cil?managed
{
??//?Code?size???????70?(0x46)
??.maxstack??2
??.locals?init?(int32?V_0)
??IL_0000:??nop
??.try
??{
????IL_0001:??nop
????IL_0002:??ldstr??????"MethodC?try"
????IL_0007:??call???????void?[mscorlib]System.Console::WriteLine(string)
????IL_000c:??nop
????IL_000d:??ldsfld?????int32?ConsoleApplication.Program::i ?//將靜態字段Program.i壓入棧中
????IL_0012:??stloc.0 ?//從棧中取出值(就是剛壓入的i),放到"第0號"臨時變量中
????IL_0013:??leave.s????IL_0043 ?//這里會退出try區塊,轉向IL_0043
??}??//?end?.try
??finally
??{
????IL_0015:??nop
????IL_0016:??ldc.i4.2 ?//在棧中放入一個4byte的數,值為2
????IL_0017:??stsfld?????int32?ConsoleApplication.Program::i ?//從棧中獲取值(剛放入的2),修改i
????IL_001c:??ldstr??????"MethodC?finally"
????IL_0021:??call???????void?[mscorlib]System.Console::WriteLine(string)
????IL_0026:??nop
????IL_0027:??ldstr??????"MethodC:"
????IL_002c:??ldsfld?????int32?ConsoleApplication.Program::i
????IL_0031:??box????????[mscorlib]System.Int32
????IL_0036:??call???????string?[mscorlib]System.String::Concat(object,
????????????????????????????????????????????????????????????????object)
????IL_003b:??call???????void?[mscorlib]System.Console::WriteLine(string)
????IL_0040:??nop
????IL_0041:??nop
????IL_0042:??endfinally
??}??//?end?handler
??IL_0043:??nop
??IL_0044:??ldloc.0 ?//將"第0號"臨時變量的值壓入棧中
??IL_0045:??ret ?//退出方法,返回值
}?//?end?of?method?Program::MethodC

  注意紅色字體部分,綠色注釋是我添加的,從上面IL及注釋可以了解到,在MethodC方法里,會有一個隱式的”第0號“變量,來臨時保存return的值,所以finally中語句雖然修改了Program.i的值,但是MethodC方法的返回值是不因finally語句而變化。

Program.MethodB();?的輸出結果,沒什么好說的,大家應該都可以準確的說出來,這里只引用CLR VIA C#上一段話將try catch 語句的執行順序簡單介紹一下:
在try塊中的代碼(或者從try塊調用的任何方法)拋出一個異常,CLR將搜索捕捉類型與拋出的異常相同(或是它的基類)的catch塊。如果沒有任何捕捉類型與拋出的異常匹配,CLR會去調用棧的更高一層搜索一個與異常匹配的捕捉類型。如果到了調用棧的頂部,還是沒有找到具有匹配捕捉類型的一個catch塊,就會發成一個未處理的異常。
  一旦CLR找到一個具有匹配捕捉類型的catch塊,就會執行內層所有finally塊中的代碼。所謂“內層finally塊”是指從拋出異常的try塊開始,到匹配異常的catch塊之間的所有finally塊。這里注意匹配異常的那個catch塊所關聯的finally塊尚未執行,該finally塊的代碼一直要等到這個catch塊中的代碼執行完畢之后才執行。

轉載于:https://www.cnblogs.com/kdalan/archive/2012/06/06/2537498.html

總結

以上是生活随笔為你收集整理的一道异常处理执行顺序面试题的简单分析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。