天天看点

【译】NoClassDefFoundError和ClassNotFoundException的不同

如果jvm或者classloader在加载类时找不到对应的类,就会引发noclassdeffounderror和classnotfoundexception,这两种错误都非常严重。由于不同的classloader会从不同的地方加载类,有时是错误的classpath引发这类错误,有时是某个库的jar包缺失引发这类错误。noclassdeffounderror和classnotfoundexception之间存在一些细微的不同点。

noclassdeffounderror表示该类在编译阶段还可以找到,但是在运行java应用的时候找不到了,有时静态块的初始化过程会导致noclassdeffounderror。

另外一方面,classnotfoundexception和编译期没什么关系,当你在程序运行时利用反射加载类时,就可能遇到classnotfoundexception异常,例如加载sql驱动时,对应的类加载器找不到驱动类。除了这些基本的不同,我们可以看看别的不同,以加深对noclassdeffounderror和classnotfoundexception的理解。

简单来说,noclassdeffounderror和classnotfoundexception都是由于在classpath下找不到对应的类而引起的,通常是缺少对应的jar包,不过,jvm认为:(1)当应用运行时没有找到对应的引用,则会抛出java.lang.noclassdeffounderror;(2)当你在代码中显式加载类(使用class.forname())时没有找到对应的类,则会抛出java.lang.classnotfoundexception。开发者经常遇到的情况是:classnotfoundexception异常引起了classnodeffounderror。

noclassdeffounderror是error,是unchecked,因此也不需要使用try-catch或者finally语句块包围;另外,classnotfoundexception是受检异常(checked exception),因此需要使用try-catch语句块或者try-finally语句块包围,否则会导致编译错误。

如果你在j2ee开发中遇到noclassdeffounderror,那么最有可能的原因就是存在多个类加载器和多个目标类,即我们常说的jar包冲突——关于jar包冲突,一般可以使用下面两种方法解决:

使用maven helper 这个插件,可以排除掉大部分jar包冲突;

根据命令<code>mvn dependency:tree -dverbose -dincludes=:logback-classic</code>

调用class.forname()、classloader.findsystemclass()和classloader.loadclass()等方法时可能会引起java.lang.classnotfoundexception

noclassdeffounderror是链接错误,发生在链接阶段,当解析引用的时候找不到对应的类,就会抛出java.lang.noclassdeffounderror;classnotfoundexception是异常,发生在运行阶段。

【译】NoClassDefFoundError和ClassNotFoundException的不同

jvm类加载阶段

最后,这里有一页非常好的ppt,总结了这两种异常的不同点:

【译】NoClassDefFoundError和ClassNotFoundException的不同

nice slide of all differences between java.lang.noclassdeffounderror and java.lang.classnotfoundexception in java

<a href="http://www.cnblogs.com/xing901022/p/4185514.html"></a>