在这个小节里,我们讨论一下ClassNotFoundException与NoClassDefFoundError的区别。
通常这两种情况都是由于程序执行期间缺少必需的.class文件,但它们之间存在差异。
ClassNotFoundException | NoClassDefFoundError |
---|---|
这通常发生在程序执行时,使用class load 语句加载缺失的.class文件:Class.forName(“class.name”);ClassLoader.loadClass(“class.name”);ClassLoader.findSystemClass(“class.name”);理由:由于运行时未更新JAR文件而执行程序,类路径中缺少必需的文件。 | 这两个错误相似,但是不同之处在于必需的.class文件在编译时可用,在运行时丢失。可能的原因:它在编译后被删除可能存在版本不匹配 |
完全限定的类名为java.lang.ClassNotFoundException | 完全限定的类名为java.lang.NoClassDefoundError |
它属于异常类别,即java.lang.Exception的直接子类。 | 它属于错误类别,即java.lang.Error, java.lang.LinkageError的子类。 |
它是一个Checked Exception,因此每当遇到如第1点所述的类装入语句时,都需要处理它。 | 所有Error都属于unchecked Exception类别,因此NoClassDeffoundError也属于unchecked Exception。 |
当检查异常时,程序员可以使用try catch块或声明throws子句来提供处理代码。因此,它是可被解决的。 | 程序执行过程中Java Runtime System 引发的错误因此,它难以复现。 |
示例1 | 示例2 |
- Class.forName(“class.name”);
- ClassLoader.loadClass(“class.name”);
- ClassLoader.findSystemClass(“class.name”);
理由:由于运行时未更新JAR文件而执行程序,类路径中缺少必需的文件。这两个错误相似,但是不同之处在于必需的.class文件在编译时可用,在运行时丢失。 可能的原因:
- 它在编译后被删除
- 可能存在版本不匹配
完全限定的类名为java.lang.ClassNotFoundException完全限定的类名为java.lang.NoClassDefoundError它属于异常类别,即java.lang.Exception的直接子类。它属于错误类别,即java.lang.Error, java.lang.LinkageError的子类。它是一个Checked Exception,因此每当遇到如第1点所述的类装入语句时,都需要处理它。所有Error都属于unchecked Exception类别,因此NoClassDeffoundError也属于unchecked Exception。当检查异常时,程序员可以使用try catch块或声明throws子句来提供处理代码。 因此,它是可被解决的。程序执行过程中Java Runtime System 引发的错误 因此,它难以复现。示例1示例2
示例1:ClassNotFoundException上的演示示例:
public class JdbcConnectionExample { public static void main(String[] args) { // declare variables // Step 1: Loading or registering Oracle JDBC driver class try { Class.forName("oracle.jdbc.driver.OracleDriver"); } catch(ClassNotFoundException cnfex) { System.out.println("Problem in loading Oracle JDBC driver"); cnfex.printStackTrace(); } // Step 2: Opening database connection } } |
---|
输出结果:
java.lang.ClassNotFoundException: oracle.jdbc.driver.OracleDriver Problem in loading Oracle JDBC driver at java.net.URLClassLoader$1.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(Unknown Source) at java.lang.ClassLoader.loadClass(Unknown Source) at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source) at java.lang.ClassLoader.loadClass(Unknown Source) at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Unknown Source) at in.bench.resources.top.exception.in.java.JdbcConnectionExample .main(JdbcConnectionExample.java:11) |
---|
在上面的例子中, 我们正在尝试使用Class.forName()静态方法加载Oracle数据库的驱动程序文件,但它在运行时不可用。 这类异常的可能原因,执行JDBC程序而不使用所需的JAR文件更新类路径, 解决方案:要纠正这个异常,只需将必需的ojdbc14.jar包含到类路径中,然后执行相同的程序。
示例2:NoClassDefoundError的演示示例:
public class SimilarException { // using below declared TestFile class static TestFile tf = new TestFile(); public static void main(String[] args) { // invoke method tf.display(); } } class TestFile { public void display() { System.out.println("Display message"); } } |
---|
运行结果:
java.lang.NoClassDefFoundError: in/bench/resources/top/exception/in/java/TestFile at in.bench.resources.top.exception.in.java.SimilarException.<clinit>( SimilarException.java:6) Caused by: java.lang.ClassNotFoundException: in.bench.resources.top.exception.in.java.TestFile at java.net.URLClassLoader$1.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(Unknown Source) at java.lang.ClassLoader.loadClass(Unknown Source) at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source) at java.lang.ClassLoader.loadClass(Unknown Source) ... 1 more Exception in thread "main" |
---|
在上面的例子中,我们编译后故意删除testfile.class以显示此异常类型. 我们正试图执行一个程序,但是classpath中缺少必须的类文件TestFile.class。 此异常类型的可能原因,在编译期间存在必需的文件,但在执行同一程序时丢失了该文件 上面的程序显示“has-a”关系,编译成功,而在程序执行期间,JVM找不到所需的.class文件。