Java基礎鞏固——異常

基礎回顧

什麼是異常?

  在Java程序運行時,常常會出現一些非正常的現象,這種情況稱爲運行錯誤。根據其性質可以分爲錯誤和異常。

Java程序中所有拋出的異常都必須從Throwable派生而來。類Throwable有兩個直接子類:Error和Exception.

  一般來說,最常見的錯誤有程序進入死循環、內存泄露等。這種情況下,程序運行時本身無法解決問題,只能通過其他程序干預。Java對應的類爲Error類。Error類對象由Java虛擬機生成並拋棄(通常Java程序不對這類異常進行處理)。

  異常是程序執行時遇到的非正常情況或意外行爲。以下這些情況一般都可以引發異常;代碼或調用的代碼中有錯誤,操作系統資源不可用,公共語言運行庫遇到意外情況。常見的有數組下標越界、算法溢出、除數爲零、無效參數、內存溢出等。這種情況不像錯誤那樣,程序運行時本身可以解決,由異常代碼調整程序運行方向,使程序仍可繼續運行,直至運行結束。

  Java異常對應的類爲Exception類。Exception類對象是Java程序處理或者拋棄的對象,它有各種不同的子類分別對應與不同類型的異常。Java編譯器要求程序必須捕獲或聲明所有的非運行時異常,但對於運行時異常可以不做處理。其中類RuntimeException代表運行時由Java虛擬機生成的異常,原因是編程錯誤。其他則爲非運行時異常,原因是程序碰到了意外情況,如輸入\輸出異常IOException等。

異常關鍵字

  Java異常處理的關鍵語句有五個:try、catch、throw、throws、finally。其中try、catch、finally三個語句塊應注意的問題如下。

  1.try、catch、finally三個語句均不能單獨使用,三者可以組合,try---catch---finally、try---catch、try---finally三種結構,catch語句可以有一個或者多個,finally語句最多一個。

  2.try、catch、finally三個代碼塊中變量的作用域爲代碼塊內部,分別獨立而不能相互訪問。如果要在三個塊中都可以訪問,則需要將變量定義到這些塊的外面。

  3.若有多個catch塊,只會匹配其中一個異常類並執行catch塊代碼,而不會執行再執行別的catch塊,並且匹配catch語句的順序是由上到下的。

  4.throw關鍵字用於方法體內部,用來拋出一個Throwable類型的異常。如果拋出了檢查異常,則還應該在頭部聲明方法可能拋出的異常類型。該方法的調用者必須檢查拋出的異常。如果所有的方法都層層上拋獲取的異常,最終JVM會進行處理會進行處理,就是打印異常消息和堆棧信息。如果拋出的Error或RuntimeException,則該方法的調用者可選擇處理該異常。

  5.thorws關鍵字用於方法體外部的方法聲明部分,用來聲明方法可能會拋出某些異常。僅當拋出了檢查異常,該方法的調用者才必須處理或者重新拋出該異常。當方法的調用者無力處理該異常的時候,應該繼續拋出,而不是囫圇吞棗地打印堆棧信息來處理。

 

異常處理中常見的問題

  1.過於龐大的try塊

  某些程序把大量的代碼塊放入當個try塊,試圖用一個catch語句捕獲所有的異常和處理所有可能出現的異常,實際上這是一個壞習慣。原因就在於爲了圖省事,不願花時間分析一大塊代碼中哪幾行會拋出異常、異常的具體類型是什麼。把大量的語句裝入單個巨大的try塊就像是出門旅遊時把全部家當塞入集裝箱帶走,雖然東西帶上了,但要找出來可不容易。

  對於這種問題,可以設置多個異常拋出點來解決。異常對象從產生點產生後,到被捕捉後終止生命的全過程中,實際上是一個傳值的過程,所以,應根據實際來合理控制異常個數。catch語句表示會出現某種異常,而且希望能夠處理該異常。所以語句中就應該儘量具體異常類型,也可以使用多個catch,用於分別處理不同的異常。

  2.異常的完整性

  在Java語言中,如果一個函數運行時可能會向上層調用者函數拋出一個異常,那麼,他就必須在該函數的聲明中顯示地註明(採用throws關鍵字)。否則編譯器會拋出錯誤信息“must be caught or declared to be thrown”,其中“must be caught”指在Java的異常處理模型中,要求所有被拋出的異常都必須有對應的“異常處理模塊”。如果你在程序中利用throw出現一個異常,那麼在你的程序中,就必須要用catch處理這個異常。

  3.RuntimeException異常

  在Java異常處理中,一般有兩類異常:其一,就是通過throw語句,程序員在代碼中人爲的拋出的異常;另外一個是系統運行時異常,例如:被零除,空字符串,無效句柄等,對於這類異常,程序員實際上完全可以避免它,只要我們寫代碼時足夠小心嚴謹。因爲,爲了徹底解決這種隱患,提高程序整體可靠性,使用RuntimeException異常就是爲了實現這樣的功能。

  針對RuntimeException類型的異常,javac是無法通過編譯的靜態語法檢測來判斷到底哪些函數可能拋出這類異常,也這因爲如此,Java異常處理模型中“must be caught or declared to be thrown”規則也不適用於次。當然RuntimeException也可以被程序顯示地拋出,而且爲了程序的可靠性,對一些可能出現的運行時異常的代碼區域,程序員最好能夠及時的處理這些異常。

 

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