Java 異常總結

Java 程序設計語言提供了三種可拋出結構(throwable):程序員

  • 受檢異常(checked exception)
  • 運行時異常(run-time exception)
  • 錯誤(error)

受檢異常

在決定使用受檢的異常或者是未受檢的異常時,主要的原則是:若是指望調用者可以適當的恢復,對於這種狀況就要使用受檢異常。經過拋出受檢異常,強迫調用者在一個 catch 子句中處理該異常,或者將它傳播出去。編程

未受檢異常

有兩種未受檢的可拋出結構:運行時異常(run-time exception) 和錯誤。併發

在行爲上二者是等同的:它們都是不須要也不該該被捕獲的可拋出結構,這種異常每每屬於不可恢復的情形,繼續執行下去有害無益。若是程序沒有捕捉到這樣的可拋出結構,將會致使當前線程中止(halt),並出現適當的錯誤信息。框架

用運行時異常來代表編程錯誤。學習

大多數的運行時異常表示前提違例(precondition violation)。所謂前提違例是指 API 的客戶沒有遵照 API 規範創建的約定。你實現的全部未受檢的拋出結構應該是 RuntimeException 的子類。線程

對於能夠恢復的狀況,使用受檢的異常;對於程序錯誤,則使用運行時異常。設計

異常也是一個徹底意義上的對象,能夠在它上面定義任意的方法。該方法的主要用途是爲捕獲異常的代碼而提供額外的信息,特別是關於引起這個異常條件的信息。調試

優先使用標準的異常

專家級程序員和缺少經驗的程序員的一個最主要的區別就是,專家追求而且一般頁呢可以實現高度的代碼重用。日誌

代碼重用是值得提倡的,這是一條通用的規則,異常也不例外。code

Java 平臺類庫提供了一組基本的未受檢的異常,他們知足了絕大多數 API 的異常拋出須要。

重用現有的異常有多方面的好處

  • 它使你的 API 更加易於學習和使用,由於它與程序員熟知的習慣用法是一致的
  • 對於用到的這些 API 程序而言, 可讀性更好,由於不會出現不少程序員不熟悉的異常。

IllegalArgumentException 是最常常被重用的。由於接收對象的狀態而使調用非法,一般就會拋出這個異常。能夠這麼說,全部錯誤的方法調用均可以被歸結爲非法參數或者非法狀態

IllegalStateException 是由於接收對象的狀態而使調用非法,一般就會拋出這個異常。

可是,其餘還有一些標準異常也被用於某些特定狀況下的非法參數和非法狀態。

如,NullPointerException 針對傳入參數爲 null 的狀況。IndexedOutOfBoundsException 針對

此外,還有一些異常,如 ConcurrentModificationException。若是一個對象被設計爲專用於單線程或者與外部同步機制配合使用,一旦發現它正在(或者已經)被併發的修改,就應該拋出這個異常。

另一個UnsupportedOperationException 。若是對象不支持所請求的操做,就會拋出這個異常。若是某個異常可以知足你的須要,就不要猶豫,使用就是,不過,必定要確保拋出異常的條件與該異常的文檔中描述的條件一致。

拋出與抽象對應的異常

若是方法拋出的異常與它所執行的任務沒有明顯的聯繫,這種情形將會令人不知所措。

爲避免此類問題,更高層的實現應該捕獲低層次的異常,同時拋出能夠按照高層抽象進行解釋的異常。這種作法稱爲異常轉譯(exception translation)。

不要忽略異常

無論異常表明了可預見的異常條件,仍是編程錯誤,用空的 catch 塊忽略它,將會致使程序在遇到錯誤的狀況下悄然的執行下去。而後,有可能在將來的某個點上,當程序不能容忍與錯誤源明顯相關的問題時,它就會失敗。

正確的處理異常功能可以完全挽回失敗。只要將異常傳播給外界,至少會致使程序迅速的失敗,從而保留了有助於調試該失敗條件的信息。

不建議使用 printStackTrace()

就是printStackTrace()打印出的堆棧日誌跟正常輸出或者業務代碼執行日誌是交錯混合在一塊兒的,在併發日誌輸出多的狀況下,查看異常日誌就變動的很是困難,由於一塊日誌都不在一塊兒了。

printStackTrace()默認使用了System.err輸出流進行輸出,與System.out是兩個不一樣的輸出流,那麼在打印時天然就造成了交叉。再就是輸出流是有緩衝區的,因此對於何時具體輸出也造成了隨機。

看到這裏就明白了,若是想簡單的讓輸出順序話,給printStackTrace()指定一個輸出流就能夠了,例如printStackTrace(System.out)

在項目中通常都是使用logback、log4j這類框架統一打印日誌,好處多多。

相關文章
相關標籤/搜索