首先,我们要了解到,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等混合使用注意代码执行顺序。不是不可以,而是越是厉害的人,代码越容易理解。