Exception和Error有什麼區別 Exception和Error都繼承了Throwable類 在Java中只有繼承了Throwable類的實例才可以被拋出(throw)或捕獲(catch) 繼承關係 Exception 程式運行過程中可以預料到的意外情況,在程式中可以進行捕獲併進行相應的處理 ...
Exception和Error有什麼區別
- Exception和Error都繼承了Throwable類
- 在Java中只有繼承了Throwable類的實例才可以被拋出(throw)或捕獲(catch)
繼承關係
Exception
程式運行過程中可以預料到的意外情況,在程式中可以進行捕獲併進行相應的處理。意思就是:這種異常發生在程式內,可以進行try..catch處理。
檢查型異常(checked exception)
必須在代碼中顯示的進行捕獲處理,編譯期會進行這一部分的檢查。例如下麵的代碼:
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
非檢查異常(unchecked exception)
也就是運行時異常(RuntimeException),例如NullPointerException、ArrayIndexOutOfBoundsException等。這類的異常時可以編碼避免的邏輯錯誤。並不會強制必須要捕獲。
Error
絕大部分的Error會導致程式(Jvm)處於不正常、不可恢復的狀態,所以不便於也不需要捕獲,例如OutOfMemoryError。
異常處理
不要捕獲Exception這樣的通用異常,應該捕獲拋出的特定異常。
不要只捕獲,不處理,忽略異常處理沒有進行日誌記錄,使得診斷錯誤難以進行。例如下麵的代碼
try { Thread.sleep(1000); //應該捕獲InterruptedException } catch (Exception e) { //直接列印沒有進行日誌記錄 e.printStackTrace(); }finally { ..... }
不要在異常的日誌中記錄用戶隱私,例如機器名,IP,埠等
try-catch會產生額外的性能開銷,會影響jvm對代碼的優化,不要用大的try包住大段代碼
每實例化一個Exception,會對當時的棧進行快照,頻繁操作會有巨大的開銷
不要在finally代碼塊中處理返回值
try代碼塊中的break或continue會使代碼進入finally代碼塊
(常見面試題)NoClassDefFoundError和ClassNotFoundException的區別
一個是Error,一個是Exception,我們不應該從Error中恢復程式運行,但可以從Exception中恢復程式運行。
NoClassDefFoundError產生的原因:
如果JVM或者ClassLoader實例嘗試載入(可以通過正常的方法調用,也可能是使用new來創建新的對象)類的時候卻找不到類的定義。要查找的類在編譯的時候是存在的,運行的時候卻找不到了。這個時候就會導致NoClassDefFoundError。
造成該問題的原因可能是打包過程漏掉了部分類,或者jar包出現損壞或者篡改。解決這個問題的辦法是查找那些在開發期間存在於類路徑下但在運行期間卻不在類路徑下的類。
ClassNotFoundException的產生原因:
Java使用反射方式在運行時動態載入類,例如使用Class.forName方法來動態地載入類,任意一個類的類名如果被作為參數傳遞給這個方法都將導致該類被載入到JVM記憶體中,如果這個類在類路徑中沒有被找到,那麼此時就會在運行時拋出ClassNotFoundException異常。 解決該問題需要確保所需的類連同它依賴的包存在於類路徑中,常見問題在於類名書寫錯誤。
還有一個導致ClassNotFoundException的原因就是:當一個類已經被類載入器載入到記憶體中了,此時另一個類載入器又嘗試著動態地從同一個包中載入這個類。通過控制動態類載入過程,可以避免上述情況發生。