NoClassDeFoundError和ClassNotFoundException
继承结构:
- NoClassDeFoundError
NoClassDeFoundError->LinkageError->Error->Throwable->Serializable - ClassNotFoundException
ClassNotFoundException->ReflectiveOperationException->Exception->Throwable->Serializable
通过对比结构可以发现他们的主要区别在于一个继承Exception,一个继承Error
- NoClassDeFoundError继承自LinkageError,根据名字我们可以猜到这是一个类加载过程中连接时错误
涉及到JVM中类加载过程
类的生命周期:
加载->(验证->准备->解析)(连接Linking)->初始化->使用->卸载
在Linking的解析阶段:解析阶段是JVM讲常量池内的符号引用替换为直接引用的过程
符号引用和直接引用
- 符号引用:就是用一组符号来描述所引用的目标,符号引用可是任何形式的字面量,只要使用时能以无歧义的定位到目标即可
- 直接引用:就是直接指向目标的指针
比如放在main函数中的
new ArrayList();
这行代码,在类生命周期的解析阶段之前,还只是符号这就是符号引用,在解析过程中,JVM回去找ArrayList是否被加载,如果未加载会先加载ArrayList,然后返回ArrayList的引用.这就是直接引用
如果在连接解析阶段找不到解析时,找不到相应的类,就会报NoClassDeFoundError.
另一方面在使用JDBC时候忘记添加驱动就会导致程序运行的时候通过类的全限定名去加载类的时候找不到这个类从而抛出ClassNotFoundException
小结:
- NoClassDeFoundError继承自Error属于用户程序无法捕获处理的异常
- ClassNotFoundException继承自Exception属于用户程序能捕获处理的异常
- NoClassDeFoundError发生在类生命周期中解析阶段找不到相应的类
- ClassNotFoundException发生在类的生命周期的加载阶段,找不到相应的类