1. ClassNotFoundException
(1) 发生原因
当通过以下3种方法根据类名加载类,但是又没有找到类的定义的时候,就会抛出ClassNotFoundException异常:
Class.forName()
ClassLoader.findSystemClass()
ClassLoader.loadClass()
(2) 类型
看ClassNotFoundException的类继承关系,它是从Exception继承下来的,因此属于程序运行中可以预料的异常,应该在代码中进行捕获,并进行相应的处理。
package test; public class TestClassLoading { public static void main(String[] args) { System.out.println("begin"); try { Class.forName("Test"); } catch(Exception e) { System.out.println("catch exception"); } System.out.println("finished"); } } class Test { public void test() { } }
(3) 代码示例
程序编译完成之后,删除Test.class文件,执行程序,这时程序会输出以下内容:
begin catch exception finished
说明程序能够捕获ClassNotFoundException异常,并且异常捕获了之后程序还能继续运行。
2. NoClassDefFoundError
(1) 发生原因
当编译的时候能够找到类定义,但是通过new的方式创建对象,或者是通过直接的方法调用的时候却找不到类定义,这时候会抛出NoClassDefFoundError异常。
(2) 类型
NoClassDefFoundError是从Error继承下来的,属于错误,JVM认为这类错误会导致程序处于非正常状态,因此不应该捕获这类异常。
(3) 代码示例
package test; public class TestClassLoading { public static void main(String[] args) { System.out.println("begin"); try { Test test = new Test(); } catch(Exception e) { System.out.println("catch exception"); } System.out.println("finished"); } } class Test { public void test() { } }
程序编译完成之后,删除Test.class文件,执行程序,这时程序会输出以下内容:
begin Exception in thread "main" java.lang.NoClassDefFoundError: test/Test at test.TestClassLoading.main(TestClassLoading.java:7) Caused by: java.lang.ClassNotFoundException: test.Test 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
因为NoClassDefFoundError不是从Exception继承下来的,因为这里的catch无法捕获到这个Error。