6 2 錯誤與異常處理

2021-10-07 23:48:15 字數 3129 閱讀 9967

一、錯誤與異常

error和exception是介面,下圖中虛線圈起來的部分屬於unchecked exception,剩餘部分屬於checked exception,unchecked型別編譯器不管,其他的編譯器會check,必須**獲或者被丟擲。

錯誤一般是指內部系統的問題,程式設計師一般對此無能為力,只能讓程式gracefully地退出;異常則是程式導致的問題,可以捕獲、處理。

二、異常處理

1、異常

異常指程式**現的非正常事件。異常可以通過異常處理程式處理,也可以丟擲異常、將資訊傳遞給上層呼叫者,然後退出。

try-catch異常處理機制可以將正常的**與異常處理**分離開,**結構清晰。

2、異常的分類

異常分為checked、unchecked兩類。unchecked包含runtimeexception及其子類,這是由程式設計師在**中處理不當造成的,可以由程式設計師檢查去避免,例如陣列越界、空指標;checked是外在問題導致的,即使程式設計師去檢查也不一定能避免(例如讀寫檔案,**中檢查了檔案是否存在,但可能執行時剛檢查完檔案是存在的,檔案就被刪除了),需要編譯器去檢查。

對於unchecked異常,不需要使用try-catch進行處理或者丟擲,編譯也會通過,但執行時會出錯。常見的有陣列越界、空指標、不合法引數、型別轉換等。

對於checked異常,要麼處理、要麼丟擲,編譯器可幫助檢查checked異常是否被處理或丟擲了。

處理checked異常的一些關鍵字:try、catch、finally、throws、throw。try-catch-finally用來捕獲和處理異常,throws表示該方法可能丟擲異常,throw用來丟擲異常。

如果對於乙個異常無能為力,就用unchecked異常,僅僅丟擲異常資訊即可;如果可以根據異常資訊對異常進行處理、恢復,就用checked異常。例如讀檔案時,如果出現檔案不存在的異常,可以讓使用者選擇其他檔案,然而如果出現了陣列越界之類的錯誤,執行時是無法進行處理的。

3、宣告異常

可能丟擲的checked異常需要在spec中宣告,需要在簽名中throws:

unchecked異常則不需要寫在規約中。因為這種異常是可以通過改**避免的,還丟擲個啥。

方法應該丟擲兩類異常:1、呼叫的函式丟擲的異常,並且沒有進行處理;2、方法自己的**丟擲的未處理的異常。

不建議宣告unchecked型別的異常,因為這種異常要麼就是沒辦法處理(error),要麼就是可以避免的(runtimeexception)。

回顧lsp替換原則,子型別可以替換父型別,要求子型別丟擲的異常也要是父型別丟擲異常的子型別或相等,不能比父型別丟擲的異常更大、更寬泛。舉個例子,下圖就是錯誤的形式,因為filenotfoundexception是ioexception的子類:

丟擲異常:找到乙個或者自己構造乙個exception類;使用new構造例項,寫入錯誤資訊;使用throw丟擲這個異常:

4、建立異常類

checked型別:建立的類要繼承(extends)自exception類,或者exception的子類。通常給出乙個預設建構函式,和乙個包含詳細資訊的建構函式:

對於checked異常,要在可能丟擲異常的方法上宣告:

unchecked型別:通常繼承runtimeexception,在可能丟擲異常的函式的簽名後面不需要宣告。

5、catch異常

異常發生後,如果沒有對異常的處理,就終止程式執行,在控制台列印stack trace。

處理異常:使用try-catch語句來捕獲異常:

無異常時,catch中的語句不執行;若出現的異常未被catch,就需要被throw出去。

對於乙個checked異常,要麼catch它,要麼使用throws傳遞(留給client去處理)。如果父型別方法沒有異常丟擲,那麼子型別必須處理所有的異常。當可能有多個異常需要catch時,一般子型別寫前面。

6、重新丟擲異常和異常鏈

在catch語句中丟擲更高階的異常,更方便客戶端獲取資訊:

最好做下圖所示操作保留根原因:

finally部分的**,不管異常是否**獲,不管發生了啥,都會執行。

乙個例子,下圖的try中丟擲了異常,**執行的順序是13456;如果在3處丟擲異常,執行的順序就是135;如果在1處丟擲了異常,沒有catch語句去捕捉,執行順序就是15:

乙個極端的例子,這裡finally最後還會執行,返回值是false:

在try後面的括號裡寫有可能需要關閉資源的語句,在try結束後會自動對資源進行關閉,但這個資源要實現autocloseable介面。

9、堆疊追蹤機制

如果乙個程式的流程是這樣:main呼叫a,a呼叫b,b呼叫c,其在棧中結構如下:

如果c中丟擲了異常,jvm從棧頂開始,向下查詢處理**catch,如果找到了就處理,找不到就終止程式。

列印出的堆疊資訊如下,最上面是異常發生的地方,最下面是最開始的呼叫:

錯誤與異常處理

內部錯誤 程式設計師通常無能為力,一旦發生,想辦法讓程式優雅的結束 異常 你自己程式導致的問題,可以捕獲 可以處理 異常 程式執行中的非正常事件,程式無法再按預想的流程執行 將錯誤資訊傳遞給上層呼叫者,並報告 案發現場 的資訊 執行時異常,是程式 源 中引入的故障所造成的 非執行時異常,是程式設計師...

PHP錯誤與異常處理

和其他程式語言遇到錯誤就丟擲異常不一樣,php在處理物件時它也有異常機制,但是php會盡可能的愉快的去執行而無視發生的事情,除非遇到乙個極端嚴重錯誤才會丟擲異常。本文概述php相關的錯誤異常處理機制。錯誤等級 php 有幾個錯誤嚴重性等級。三個最常見的的資訊型別是錯誤 error 通知 notice...

Python 錯誤與異常處理

python 有兩種錯誤型別 1 語法錯誤 syntax errors 2 異常 exceptions 語法錯誤就不說了 關於異常處理 用try except 首先try 和 except 之間的 首先被執行,如果沒有異常,則except語句將會被忽略,如果出現異常,則try下的語句將會被忽略,直接...