两个异常都和找不到类有关,但引发这两个异常的原因有所不同。
ClassNotFoundException
是在我们主动使用类名加载类时找不到对应类文件抛出的异常,这是一个Exception
,需要我们显式捕获处理。参考ClassNotFoundException
的JavaDoc:Thrown when an application tries to load in a class through its string name using:
- The forName method in class Class.
- The findSystemClass method in class ClassLoader .
- The loadClass method in class ClassLoader.
but no definition for the class with the specified name could be found.
NoClassDefFoundError
是系统被动加载类时(例如使用new
关键字),找不到对应类文件而抛出的异常,这是一个Error
,继承自LinkageError
,即编译期使用的类定义在运行期无法找到,或者不兼容。参考NoClassDefFoundError
的JavaDoc:Thrown if the Java Virtual Machine or a ClassLoader instance tries to load in the definition of a class (as part of a normal method call or as part of creating a new instance using the new expression) and no definition of the class could be found.
The searched-for class definition existed when the currently executing class was compiled, but the definition can no longer be found.
引起类找不到的主要原因如下
- 类不在classpath中
- 运行时指定的classpath错误
- jar manifest文件中设置classpath错误
- 例如maven-jar-plugin的这个bug会导致snapshot包在lib目录中和mf文件中的文件名不一致
- 依赖冲突导致加载的类和编译的类不同
- 类加载时,静态块或静态变量初始化失败,这种情况日志中会有
ExceptionInInitializerError
- classloader可见性问题,例如在tomcat容器中使用common loader无法加载到webapp中的类
参考:
https://javarevisited.blogspot.com/2011/06/noclassdeffounderror-exception-in.html
[[java]]