首先,我們要瞭解到,NoClassDefFoundError是一個錯誤(Error),而ClassNOtFoundException是一個異常(Exception),在Java中對於錯誤和異常的處理是不同的,我們可以從異常中恢復程序但卻不應該嘗試從錯誤中恢復程序。
ClassNotFoundException的產生原因:
Java支持使用Class.forName方法來動態地加載類,任意一個類的類名如果被作爲參數傳遞給這個方法都將導致該類被加載到JVM內存中,如果這個類在類路徑中沒有被找到,那麼此時就會在運行時拋出ClassNotFoundException異常。
try {
Class.forName("xxx");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
這一段代碼,我們運行的時候,就會拋出ClassNotFoundException異常,而異常可以捕獲,所以我們可以用try-catch來進行捕獲。
NoClassDefFoundError產生的原因在於:
如果JVM或者ClassLoader實例嘗試加載(可以通過正常的方法調用,也可能是使用new來創建新的對象)類的時候卻找不到類的定義。要查找的類在編譯的時候是存在的,運行的時候卻找不到了。這個時候就會導致NoClassDefFoundError.
造成該問題的原因可能是打包過程漏掉了部分類,或者jar包出現損壞或者篡改。解決這個問題的辦法是查找那些在開發期間存在於類路徑下但在運行期間卻不在類路徑下的類。
List<User> users = new ArrayList<User>();
for(int i=0; i<2; i++){
try{
//第一次只是會拋出異常,導致類加載不到,第二次就會出錯
System.out.println(i);
users.add(new User(String.valueOf(i))); //will throw NoClassDefFoundError
}catch(Throwable t){ //NoClassDefFoundError 是 error
t.printStackTrace();
}
}
class User{
private static String USER_ID = getUserId();
public User(String id){
this.USER_ID = id;
}
private static String getUserId() {
//拋出異常,類定義失敗,就會報錯
throw new RuntimeException("UserId Not found");
}
}
1.Error:系統錯誤,虛擬機出錯,我們處理不了,也不需要我們來處理。
2.Exception,可以捕獲的異常,且作出處理。也就是要麼捕獲異常並作出處理,要麼繼續拋出異常。
3.RuntimeException,經常性出現的錯誤,可以捕獲,並作出處理,可以不捕獲,也可以不用拋出。ArrayIndexOutOfBoundsException像這種異常可以不捕獲,爲什麼呢?在一個程序裏,使用很多數組,如果使用一次捕獲一次,則很累。
4.繼承某個異常時,重寫方法時,要麼不拋出異常,要麼拋出一模一樣的異常。
5.當一個try後跟了很多個catch時,必須先捕獲小的異常再捕獲大的異常。
6.假如一個異常發生了,控制檯打印了許多行信息,是因爲程序中進行多層方法調用造成的。關鍵是看類型和行號。
7.上傳下載不能拋異常。上傳下載一定要關流。
8.異常不是錯誤。異常控制代碼流程不利於代碼簡單易讀。
9.try catch fnally執行流程,與 return, break, continue等混合使用注意代碼執行順序。不是不可以,而是越是厲害的人,代碼越容易理解。