物件導向 錯誤與異常

2021-10-04 23:49:43 字數 4640 閱讀 4485

對於.net類一般的異常類system.exception派生自system.object,通常不在**中丟擲system.exception泛型物件,因為他們無法確定錯誤情況的本質。

在該層次結構中有兩個重要的類,他們派生自system.exception。

system.systemexception-該類用於通常由.net執行庫丟擲的異常,或者有著非常一般的本質並且可以由幾乎所有的應用程式丟擲的異常。例如,如果.net執行庫檢測到呼叫方法時引數不正確,就可以在自己的**中丟擲argumentexception異常或其子異常。system.systemexception異常的子類,包括表示致命錯誤和非致命錯誤的異常。

stackoverflowexception 如果分配給棧的記憶體區域已滿,就會丟擲這個異常。如果乙個方法連續地遞迴呼叫自己,就可能發生棧溢位。這一般是乙個致命錯誤,因為它禁止應用程式執行除了中斷以外的其他任務。在這種情況下,甚至也不可能執行finally塊,通常使用者自己不能處理像這樣的錯誤,而應退出應用程式。

endofstreamexception 這個異常通常是因為讀到檔案末尾而丟擲的。

overflowexception 如果要在checked環境下把包含-40的int型別資料強制轉換為unit資料,就會丟擲異常。

捕獲異常

為了在c#**中處理可能的錯誤情況,一般要把程式的相關部分分成3種不同的**塊:

使用步驟:

執行的程式流進try塊。

如果try塊中沒有錯誤發生,在塊中正常執行。當程式流到try塊末尾後,如果存在乙個finally塊,程式就會自動進入finally塊。但如果在try塊中程式流檢測到乙個錯誤,程式流就會跳轉到catch塊。

在catch中處理錯誤。

在catch塊執行完成後,如果存在finally塊,程式流就會自動進入finally塊。

執行finally塊。

例 :try

catch

finally

實際上,上面的**還有幾種變體:

catch(overflowexception ex)

假定可能在try塊中發生兩個嚴重錯誤:溢位和陣列超出範圍。假定**包含兩個布林變數overflow和outofbounds,它們分別表示這兩種錯誤的存在,如下所示:

tryif (outofbounds==true)

}catch(overflowexception ex)

catch( indexoutofrangeexception ex)

finally

throw 語句可以巢狀在try塊幾個方法呼叫中,甚至在程式流進入其他方法時,也會繼續執行同乙個try塊。如果計算機遇到一條throw 語句,就會立即退出棧上所有的方法呼叫,查詢try塊的結尾和合適的catch塊的開頭,此時,中間方法呼叫的所有區域性變數超出作用域。try ….catch結構最適合於本屆開頭描述的場合;錯誤發生在乙個方法呼叫中,而該方法呼叫可能巢狀了15級或者20級,這些處理操作會立即停止。

try塊在控制執行得程式流上有重要的作用。但是,異常時用於處理異常情況的,不應該用異常來控制退出 do….. while迴圈時間。

例:using system;

namespace wrox.procsharp.advancedcsharp

catch (indexoutofrangeexception e)

catch (exception e)

catch

finally}}

}}注:1、傳遞給catch塊的引數只能用於該catch塊。這就是為什麼在上面的**中能在後續的catch塊中使用相同的引數ex的原因。

2、這裡用break語句退出try塊和while迴圈。這是有效的,當程式流退出try塊時,會執行finally塊的語句。

下面的異常:

if (index<0||index>5)

在丟擲乙個異常時,需要選擇丟擲異常的型別。可以使用system.exception異常類,但這個類是乙個基類,最好不要把這個類的例項當做乙個異常丟擲,因為他沒有包含錯誤的任何資訊。而.netframework包含了許多派生自system.exception異常類的其他異常類,每個都對應於一種特定型別的異常情況,也可以定義異常類。在丟擲乙個匹配特定錯誤情況的類的例項時,應提供盡可能多的資訊。在本例中,system.indexoutofrangeexception異常類是最佳選擇。

假定使用者這次輸入了不在0-5範圍內的數字,if語句就會檢測到乙個錯誤,並例項化和丟擲乙個indexoutofrangeexception異常物件。計算機會立即退出try塊,並查詢處理indexoutofrangeexception異常的catch塊。

catch (indexoutofrangeexception e)

由於這個catch塊帶適合的乙個引數,因此它就會傳遞給異常例項,並執行。在本例是顯示錯誤資訊和exception.message屬性。執行了這個catch塊後,控制權就切換到finally塊,就好像沒有發生過任何異常。

catch (exception e)

沒有前面的catch塊中捕獲異常,則這個catch塊也能處理indexoutofrangeexception異常。基類的乙個引用也可以指派生自它的類的所欲例項,所有的異常都派生自system.exception異常類。那麼為什麼不執行這個catch塊?答案是計算機指執行它在可用的catch塊列表中找到的第乙個適合的catch塊。但為什麼這要編寫第二個catch塊?不僅try塊包含這段**,這有另外3個方法去呼叫console.readline(),console.write(),convert.toint32()也包含這段**,他們是system命名空間的方法。這個方法也會丟擲異常。

如果輸入a或者hello,convert.toint32()方法就會丟擲system.formatexception類的乙個異常,表達傳遞給toint32()方法的字串對應的格式不能轉換為int。此時,計算機會跟蹤這個方法呼叫,查詢可以處理該異常的處理程式。第乙個catch塊不能處理這種異常,因為formatexception派生與exception異常類,所以把formatexception異常類的例項作為引數傳遞給它。

該例項的這種結構是非常典型的多catch結構。最先編寫的catch用子處理非常特殊的錯誤情況,接著是比較一般的塊,他們可以處理任何錯誤。

catch塊的順序非常重要,如果這兩個catch塊順序相反的話,**不會編譯。因此最上面的catch應用於最特殊的異常情況,最後是一般的catch塊。

system.exception屬性

屬性

說明

data

這個屬性可以給異常新增鍵/值語句,以提供關於異常的額外資訊

helplink

鏈結到乙個幫助檔案上,以提供關於該異常的更多資訊

innerexception

如果此異常時在catch塊中丟擲的,它就會包含**傳送到catch中的異常物件。

message

描述錯誤情況的文字

source

導致異常的應用程式名或物件名

stacktrace

棧上方法呼叫的詳細資訊,它有助於跟蹤丟擲異常的方法。

targetsite

描述丟擲異常的方法的.net反射物件

在這些屬性中,如果可以進行棧跟蹤,stacktrace和targetsite屬性由.net執行庫自動提供。source屬性總是有.net執行庫填充為丟擲異常的程式集的名稱(但在**中可以修改,以提供更多的資訊),data,message,helplink和innerexception屬性必須在丟擲異常的**中填充,方法時在丟擲異常前設定這些屬性。例:

if (errorcondition==true)

如果丟擲異常,**中沒有catch塊能處理這類異常,則有.net執行庫捕獲它。

巢狀的try塊

異常的乙個特性是try塊可以巢狀,如下:

trycatch

finally

//point d

}catch

finally

如果丟擲的異常在外層的 try 塊中,在標記為 a點 和 d點 的**塊:異常由外層的 catch塊 捕獲,並執行外層的 finally塊 ,或者執行 finally塊,由 .net運 行庫處理異常。

如果異常是在內層try塊標記為 b點 的**塊中丟擲的,且有乙個合適的內層 catch塊處理該異常,在內層處理異常,執行內層的 finally塊 ,之後執行標記為 d點的**塊。

在內層丟擲異常,且內層沒有找到合適的處理程式。這是會執行內層finally塊,但接著.net執行庫退出內層的try塊,到外層的catch塊中尋找合適的catch,如果找到後執行finally塊,如果沒有找到執行完finally塊後,控制權轉移給.net執行庫。注意:任何時候都不會執行標記點d的**。

如果在c點丟擲異常,如果程式執行到c點中,它就必須處理在b點丟擲的異常。在catch塊中丟擲另乙個異常很正常。此時,異常的處理跟它是外層try塊中丟擲的一樣,程式流會立即退出內層的catch塊,執行內層的finally塊,系統在外層的catch塊中搜尋處理程式。同樣,在內層的finally塊中丟擲乙個異常,搜尋會在外層的catch塊開始,控制權會立即轉移到最匹配的處理程式。

try塊的巢狀也可能發生在方法之間。例:如果方法a呼叫了try塊中的方法b,那麼方法b也包含乙個try塊。

為什麼要用巢狀?

為了修改所丟擲的異常的型別。

為了能夠在**的不同地方處理不同的異常。

物件導向 異常

異常 exception 1.定義 就是導致程式終止的一種指令流,異常會使程式終止執行 2.throw和throws a throw用於丟擲一場物件 b throws用於標識函式暴露出的異常 區別 a throw用在函式上,後面跟異常類名 b throws用在函式內,後面跟異常物件 3.異常細節 a...

物件導向 異常finally

finally 塊 定義一定執行的 通常用於關閉資源。class fushuexception extends exception class demo class exceptiondemo5 catch fushuexception e finally system.out.println ov...

物件導向 異常 RuntimeException

exceptoin 中有乙個特殊的子類異常 runtimeexception 如果在函式內容丟擲該異常,函式上可以不用宣告,編譯一樣通過。如果在函式上宣告了該異常,呼叫者可以不用進行處理,編譯一樣通過。自定義異常時 如果該異常的發生無法在繼續進行運算,就讓自定義異常繼承runtimeexceptio...