在java开发中经常遇到的两个异常, ClassNotFoundException 和NoClassDefFoundError。
表面看起来都是类找不到的异常,但是具体又有什么区别呢?
如它们的名字所说明的:NoClassDefFoundError是一个错误(Error),而ClassNOtFoundException是一个异常。
在Java中错误和异常是有区别的,我们可以从异常中恢复程序但却不应该尝试从错误中恢复程序,
也就是说Exception我们可以用try …catch…等手段让程序继续运行,而Error发生时我们并不能恢复程序的正常执行。
ClassNotFoundException:
ClassNotFoundException 通常在编译的时候会暴露,但是也可以在运行时出现,因为java有反射和类的动态加载。Java支持使用Class.forName方法来动态地加载类,任意一个类的类名如果被作为参数传递给这个方法都将导致该类被加载到JVM内存中,如果这个类在类路径中没有被找到,那么此时就会在运行时抛出ClassNotFoundException异常。那么通常导致此问题可能的原因有:
1)缺jar包,会出现。
2)不缺jar包,依赖有冲突,且在动态加载(尤其是在Spring/Dubbo等框架)中,也可能会出现。
3)不缺jar包,也没有冲突依赖,但是有类隔离,还是可能会出现(例如框架执行过程中存在自定义的ClassLoader,打破了双亲委派机制),同样做法的还有tomcat容器。
NoClassDefFoundError:
NoClassDefFoundError 当包冲突是可能会出现。但并不仅因为缺少包或类冲突,而是类初始化失败。
如果JVM或者ClassLoader实例尝试加载(可以通过正常的方法调用,也可能是使用new来创建新的对象)类的时候却找不到类的定义。要查找的类在编译的时候是存在的,运行的时候却找不到了。这个错误往往是你使用new操作符来创建一个新的对象但却找不到该对象对应的类。这个时候就会导致NoClassDefFoundError.由于NoClassDefFoundError是有JVM引起的,所以不应该尝试捕捉这个错误。可以简单的理解为:
是new 失败,再进一步可能是:
1)私有成员变量初始化失败。
2)静态成员变量初始化失败。
3)静态代码块执行异常。。。