1. 程式人生 > >每日一題:Java異常處理

每日一題:Java異常處理

增加 異常處理 int throwable 邏輯 現實 inter throws 運行時

什麽是異常

在理想情況下,程序總會運行在很完美的環境中,網絡不會終端,文件一定存在,程序不會有 BUG。但是,理想很豐滿,現實很骨幹,實際生產環境中,網絡可能會中斷,文件可能會找不到,內存可能會溢出,程序可能會有 BUG。而這些意料之外的情況就是異常。

在未處理的情況下,異常會導致程序無法繼續執行,從而影響軟件整體的功能,但這是多數情況下不允許的,所以我們需要在程序中將可處理的異常處理掉,至少保證當前任務可以安全退出。

Java 異常

Java 異常體系中,Throwable 為超類,其子類包括 Error 和 Exception 兩類,Error 主要包括 JVM 本身的問題,這一類問題很少出現且無法被程序所解決,所以代碼中可以不考慮此部分。

Java 異常體系將異常分為檢查異常(checked exception)和未檢查異常(unchecked exception)。

未檢查異常也可叫做運行時異常,因為其在 Java 異常體系中僅包含 RuntimeException,主要包括代碼編寫時人為因為做成的異常,而這些異常在代碼編譯階段無法發現,常見的有 IndexOutOfBoundsException、NullPointerException 和 IndexOutOfBoundsException 等,當出現未檢查異常時可確定是代碼 BUG。

檢查異常包括除 RuntimeException 以外的所有異常,常見的主要為 IOException 和 SQLExcetion 兩類,此部分異常雖然可能為人為造成,但在代碼編譯階段就可以被編譯器發現,所以需要在代碼中做好相應的處理。

Java 異常處理

對應異常體系,Java 提供了異常處理機制,常用的關鍵字有 try、catch、finally、throw 和 throws。

try、catch 和 finally 的用法比較簡單,只需要符合標準語法即可,try 對代碼塊進行監聽,當出現異常時 catch 捕獲異常進行異常處理,最後執行 finally 代碼塊。需要註意幾個點:

  • 是無論是否出現異常,finally 代碼塊是一定執行,且在最後執行
  • catch 可以出現多次,但出現多次時需要註意異常的父子級關系,後面的異常不能為前面的子類
try{
    // 代碼塊
} catch (異常){
    // 異常處理代碼
} finally {
    // 需要確保一定執行的代碼,例如關閉流資源占用的代碼
}

throw 和 throws 比較容易混淆。throw 用於在代碼中手動拋出異常,而 throws 則用於在方法簽名後聲明需要拋出的異常,涉及到繼承關系時,子類方法拋出異常時,父類方法必須拋出異常,不能為子類異常的子類且數量不能少於子類,代碼結構如下:

public void testMethod() throw Exception{
    throw new RuntimeException();
}

Java 異常的使用建議

  • 僅當有需要或者能處理時對異常進行捕獲,否則將異常拋向調用者,直至到與頁面進行交互時統一處理或記錄日誌
  • finally 代碼塊建議只用來釋放占用的資源,不要用來處理業務邏輯
  • 不要通過異常處理機制處理 RuntimeException,因為此類異常可以通過修改代碼來解決,同時增加程序的健壯性
  • 異常處理記錄日誌時記錄對問題排查有用的信息,無法確定時則將異常堆棧信息及方法運行參數記錄下來
  • catch 捕獲異常時粒度盡可能,例如捕獲 FileNotFoundException 時不要用 IOException 代替
  • try 監聽的代碼盡可能少,不要將整個方法體都放在 try 語句中

每日一題:Java異常處理