【java基礎(四十五)】異常(一)處理錯誤和異常分類

在理想狀態下,用戶輸入數據的格式永遠都是正確的,選擇打開的文件也一定存在,並且永遠不會出現bug,迄今爲止,呈現給大家的代碼似乎都處在這樣一個理想境界中。然而,在現實世界中卻充滿了不良的數據和帶有問題的代碼,我們接下來討論一下Java程序設計語言處理這些問題的機制。

人們在遇到錯誤時會感覺不爽。如果一個用戶在運行程序期間,由於程序的錯誤或一些外部環境的影響造成用戶數據的丟失,用戶就有可能不再使用這個程序了。爲了避免這類事情的發生,至少應該做到以下幾點:

  • 向用戶通告錯誤。
  • 保存所有的工作結果。
  • 允許用戶以妥善的形式退出程序。

對於異常情況,例如,可能造成程序崩潰的錯誤輸入,Java使用一種稱爲異常處理(exception handing)的錯誤捕獲機制處理。

錯誤處理

假設在一個Java程序運行期間出現了一個錯誤。這個錯誤可能是由於文件包含了錯誤信息,或者網絡連接出現問題造成的,也有可能是因爲使用無效的數組下標,或者試圖使用一個沒有被賦值的對象引用而造成的。用戶期望在出現錯誤時,程序能夠採用一些理智的行爲。如果由於出現錯誤而使得某些操作沒有完成,程序應該:

  • 返回到一種安全狀態,並能夠讓用戶執行一些其他的命令。
  • 允許用戶保存所有操作的結果,並以妥善的方式終止程序。

要做到這些並不是一件很容易的事情。其原因是檢測(或引發)錯誤條件的代碼通常離那些能夠讓數據回覆到安全狀態,或者能夠保存用戶的操作結果,並正常地退出程序的代碼很遠。異常處理的任務就是將控制權從錯誤產生的地方轉移給能夠處理這種情況的錯誤處理器。爲了能夠在程序中處理異常情況,必須研究程序中可能出現的錯誤和問題,以及哪類問題需要關注。

  1. 用戶輸入錯誤
    除了那些不可避免的鍵盤輸入錯誤外,有些用戶喜歡各行其是,不遵守程序的要求。例如,假設有一個用戶請求連接的一個URL,而語法卻不正確。在程序代碼中應該對此進行檢查,如果沒有檢查,網絡層就會給出警告。
  2. 設備錯誤
    硬件並不總是讓它做什麼,它就做什麼。打印機可能被關掉了。網頁可能臨時性地不能瀏覽。在一個任務的處理過程中,硬件經常出現問題。例如,打印機在打印過程中可能沒有紙了。
  3. 物理限制
    磁盤滿了,可用存儲空間已被用完。
  4. 代碼錯誤
    程序方法有可能無法執行。例如,方法可能返回一個錯誤的答案,或者錯誤地調用了其他的方法。計算的數組索引不合法,試圖在散列表中查找一個不存在的記錄,或者試圖讓一個空棧執行彈出操作,這些都屬於代碼錯誤。

對於方法中的一個錯誤,傳統的做法就是返回一個特殊的錯誤碼,由調用方法分析。例如,對於一個從文件中讀取信息的方法來說,返回值通常不是標準字符,而是一個-1,表示文件結束。這種處理方式對於很多異常狀況都是可行的。還有一種表示錯誤狀況的常用返回值是null引用。

遺憾的是,並不是在任何情況下都能夠返回一個錯誤碼。有可能無法明確地將有效數據與無效數據加以區分。一個返回整型的方法就不能簡單地通過返回-1表示錯誤,因爲-1很可能是一個完全合法的結果。

在Java中,如果某個方法不能夠採用正常的途徑完成它的任務,就可以通過另外一個路徑退出方法。在這種情況下,方法並不返回任何值,而是拋出(throw)一個封裝了錯誤信息的對象。需要注意的是,這個方法將會立刻退出,並不返回任何值。此外,調用這個方法的代碼也將無法繼續執行,取而代之的是,異常處理機制開始搜索能夠處理這種異常狀況的異常處理器(exception handler)。

異常分類

在Java程序設計語言中,異常對象都是派生於Throwable類的一個實例。當然,如果Java中內置的異常類不能夠滿足需求,用戶可以創建自己的異常類。

異常層次結構的簡化示意圖:
在這裏插入圖片描述
需要注意的是,所有的異常都是由Throwable繼承而來,但在一下層立即分解爲兩個分支:Error和Exception。

Error類層次結構描述了Java運行時系統的內部錯誤和資源耗盡錯誤。應用程序不應該拋出這種類型的對象。如果出現了這樣的內部錯誤,除了通告給用戶,並盡力使程序安全地終止之外,再也無能爲力了。這種情況很少出現。

在設計Java程序時,需要關注Exception層次結構。這個層次結構又分解爲兩個分支:一個分支派生於RuntimeException;另一個分支包含其他異常。劃分兩個分支的規則是:由程序錯誤導致的異常屬於RuntimeException;而程序本身沒有問題,但由於想I/O錯誤這類問題導致的異常屬於其他異常。

派生於RuntimeException的異常包含下面幾種情況:

  • 錯誤的類型轉換。
  • 數組訪問越界。
  • 訪問null指針。

不是派生於RuntimeException的異常包括:

  • 試圖在文件尾部後面讀取數據。
  • 試圖打開一個不存在的文件。
  • 試圖根據給定的字符串查找Class對象,而這個字符串表示的類並不存在。

“如果出現RuntimeException異常,那麼就一定是你的問題”是一條相當有道理的規則。應該通過檢測數組下標是否越界來避免ArrayIndexOutOfBoundsException異常;應該通過在使用變量之前檢測是否爲null來杜絕NullPointException異常的發生。

如何處理不存在的文件呢?難道不能先檢查文件是否存在再打開它嗎?嗯,這個文件有可能在你檢查它是否存在之前就已經被刪除了。因此,“是否存在”取決於環境,而不只是取決於你的代碼。

Java語言規範將派生於Error類或RuntimeException類的所有異常稱爲非受查(unchecked)異常,所以其他的異常稱爲受查(checked)異常。這是兩個很有用的術語,在後面還會用到。編譯器將檢查是否所有的受查異常提供了異常處理器。

捐贈

若你感覺讀到這篇文章對你有啓發,能引起你的思考。請不要吝嗇你的錢包,你的任何打賞或者捐贈都是對我莫大的鼓勵。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章