极客时间课程《JAVA核心技术面试精讲》
Exception和Error区别
典型回达
Exception 和 Error 都是继承了 Throwable 类,只有 Throwable 类型的实例才可以被抛出(throw)或者捕获(catch)。
- Exception是正常运行中,可预料的意外情况,应该被捕获并处理。
- Error是正常情况下,不大可能出现的情况,绝大部分的 Error 都会导致程序(比如 JVM 自身)处于非正常的、不可恢复状态。比如 OutOfMemoryError 之类,都是 Error 的子类。
- Exception包含:可检查异常和不检查异常,可检查异常必须在源码里显示的捕获处理,编译期会检查。不检查异常指运行时异常,比如NullPointerException、ArrayIndexOutOfBoundsException
考点分析
1 NoClassDefFoundError 和 ClassNotFoundException 区别
ClassNotFoundException
: 是一个检查时异常(checked exception),它在应用程序试图通过字符串名称动态加载类并且找不到相应的类时抛出。这种情况通常发生在使用Class.forName()
,ClassLoader.loadClass()
或者java.net.URLClassLoader.findSystemClass()
等方法时。try { Class<?> cls = Class.forName("com.example.NonExistingClass"); } catch (ClassNotFoundException e) { e.printStackTrace(); }
- 典型的情况是,类路径上确实没有这个类,或者在运行时动态加载类时提供了错误的类名 - `NoClassDefFoundError`是一个错误(Error),它表示JVM在之前已经加载过类的定义,但现在在运行时找不到类的定义了。这通常是因为在编译时类是可用的,但在运行时因为某些原因类路径改变了或者相应的类文件被移动、删除或损坏,导致JVM无法找到类的定义。 - 这个错误也可能发生在类初始化失败之后的第二次尝试加载这个类时,因为Java虚拟机规范允许类初始化失败后进行后续尝试。 - ```java public class MyClass { static { int[] counts = new int[-1]; // 引发异常的静态初始化器 } } public class Test { public static void main(String[] args) { try { MyClass myObj = new MyClass(); } catch (Throwable e) { e.printStackTrace(); } MyClass myObj2 = new MyClass(); // 这里会抛出NoClassDefFoundError } }
在第一次尝试创建
MyClass
的实例时,由于静态初始化器中有错误,会抛出一个ExceptionInInitializerError
。如果后面再次尝试创建MyClass
的实例,由于类初始化已经失败,JVM不会再次尝试初始化类,而是直接抛出NoClassDefFoundError
。