身处险境的人总在谋求安稳,活于规定的人又在追赶自在。
在写 Java 程序的时候,当一个类找不到的时候,JVM 有时候会抛出 ClassNotFoundException 异样,而有时候又会抛出 NoClassDefFoundError。看两个异样的字面意思,如同都是类找不到,然而 JVM 为什么要用两个异样去区分类找不到的状况呢?这个两个异样有什么不同的中央呢?
ClassNotFoundException
ClassNotFoundException 是一个运行时异样。从类继承档次上来看,ClassNotFoundException 是从 Exception 继承的,所以 ClassNotFoundException 是一个查看异样。
当利用程序运行的过程中尝试应用类加载器去加载 Class 文件的时候,如果没有在 classpath 中查找到指定的类,就会抛出 ClassNotFoundException。个别状况下,当咱们应用 Class.forName() 或者 ClassLoader.loadClass 以及应用 ClassLoader.findSystemClass() 在运行时加载类的时候,如果类没有被找到,那么就会导致 JVM 抛出 ClassNotFoundException。
最简略的,当咱们应用 JDBC 去连贯数据库的时候,咱们个别会应用 Class.forName() 的形式去加载 JDBC 的驱动,如果咱们没有将驱动放到利用的 classpath 下,那么会导致运行时找不到类,所以运行 Class.forName() 会抛出 ClassNotFoundException。
public class MainClass {public static void main(String[] args) {
try {Class.forName("oracle.jdbc.driver.OracleDriver");
} catch (ClassNotFoundException e) {e.printStackTrace();
}
}
}
输入:
java.lang.ClassNotFoundException: oracle.jdbc.driver.OracleDriver
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:264)
at MainClass.main(MainClass.java:7)
NoClassDefFoundError
NoClassDefFoundError 异样,看命名后缀是一个 Error。从类继承档次上看,NoClassDefFoundError 是从 Error 继承的。和 ClassNotFoundException 相比,显著的一个区别是,NoClassDefFoundError 并不需要应用程序去关怀 catch 的问题。
当 JVM 在加载一个类的时候,如果这个类在编译时是可用的,然而在运行时找不到这个类的定义的时候,JVM 就会抛出一个 NoClassDefFoundError 谬误。比方当咱们在 new 一个类的实例的时候,如果在运行是类找不到,则会抛出一个 NoClassDefFoundError 的谬误。
public class TempClass {
}
public class MainClass {public static void main(String[] args) {TempClass t = new TempClass();
}
}
首先这里咱们先创立一个 TempClass,而后编译当前,将 TempClass 生产的 TempClass.class 文件删除,而后执行程序,输入:
Exception in thread "main" java.lang.NoClassDefFoundError: TempClass
at MainClass.main(MainClass.java:6)
Caused by: java.lang.ClassNotFoundException: TempClass
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 1 more
总结