天天看點

Java -- 每日一問:Exception 和 Error 有什麼差別?

Java -- 每日一問:Exception 和 Error 有什麼差別?

典型回答

Exception 和 Error 都是繼承了 Throwable 類,在 Java 中隻有 Throwable 類型的執行個體才可以被抛出(throw)或者捕獲(catch),它是異常處理機制的基本組成類型。

Exception 和 Error 展現了 Java 平台設計者對不同異常情況的分類。Exception 是程式正常運作中,可以預料的意外情況,可能并且應該被捕獲,進行相應處理。

Error 是指在正常情況下,不大可能出現的情況,絕大部分的 Error 都會導緻程式(比如 JVM 自身)處于非正常的、不可恢複狀态。既然是非正常情況,是以不便于也不需要捕獲,常見的比如 OutOfMemoryError 之類,都是 Error 的子類。

Exception 又分為可檢查(checked)異常和不檢查(unchecked)異常,可檢查異常在源代碼裡必須顯式地進行捕獲處理,這是編譯期檢查的一部分。前面我介紹的不可查的 Error,是 Throwable 不是 Exception。

不檢查異常就是所謂的運作時異常,類似 NullPointerException、ArrayIndexOutOfBoundsException 之類,通常是可以編碼避免的邏輯錯誤,具體根據需要來判斷是否需要捕獲,并不會在編譯期強制要求。

高手回答

NoClassDefFoundError是一個錯誤(Error),而ClassNOtFoundException是一個異常,在Java中對于錯誤和異常的處理是不同的,我們可以從異常中恢複程式但卻不應該嘗試從錯誤中恢複程式。

ClassNotFoundException的産生原因:

Java支援使用Class.forName方法來動态地加載類,任意一個類的類名如果被作為參數傳遞給這個方法都将導緻該類被加載到JVM記憶體中,如果這個類在類路徑中沒有被找到,那麼此時就會在運作時抛出ClassNotFoundException異常。

ClassNotFoundException的産生原因:

Java支援使用Class.forName方法來動态地加載類,任意一個類的類名如果被作為參數傳遞給這個方法都将導緻該類被加載到JVM記憶體中,如果這個類在類路徑中沒有被找到,那麼此時就會在運作時抛出ClassNotFoundException異常。

ClassNotFoundException的産生原因主要是:

Java支援使用反射方式在運作時動态加載類,例如使用Class.forName方法來動态地加載類時,可以将類名作為參數傳遞給上述方法進而将指定類加載到JVM記憶體中,如果這個類在類路徑中沒有被找到,那麼此時就會在運作時抛出ClassNotFoundException異常。

解決該問題需要確定所需的類連同它依賴的包存在于類路徑中,常見問題在于類名書寫錯誤。

另外還有一個導緻ClassNotFoundException的原因就是:當一個類已經某個類加載器加載到記憶體中了,此時另一個類加載器又嘗試着動态地從同一個包中加載這個類。通過控制動态類加載過程,可以避免上述情況發生。