欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Exception 和 Error 有什么区别

程序员文章站 2022-04-19 22:32:29
...

一、对比 Exception 和 Error

①Exception 和 Error 都继承了 Throwable 类,在 Java 中只有 Throwable 类型的实例才可以被抛出(throw)或捕获(catch)
②Error 是指在正常情况下,不大可能出现的情况,大部分 Error 都会导致程序处于非正常、不可恢复状态,所以对于 Error 即便捕获了很可能也无法处理或恢复,因此也就没必要对其进行捕获
③Exception 又分为可检查异常和未检查异常,对于可检查异常在代码中必须显式的进行捕获处理

二、异常处理实践

2.1 例子

try {
	Thread.sleep(1000L);
} catch (Exception e) {
	// Ignore it
}

上面的代码,违反了异常处理的两个基本原则:
1.尽量不要捕获类似 Exception 这样的通用异常,而是应该捕获具体异常
因此这里应该捕获的是 Thread#sleep() 抛出的 InterruptedException
2. 不要生吞异常,这在异常处理中需要特别注意,因为很可能会产生难以诊断的情况

2.2 自定义异常

自定义异常须知:
1.应当提供足够的信息,但不要包含敏感信息(如用户数据等)
2.根据需要决定是否定义成可检查异常,即出现异常后可以从异常中恢复

2.3 可优化的操作

1.异常采用 Throw early,catch late 原则
throw early:第一时间暴露可能出现的异常,对应的异常信息会更直观
catch late:如果不知道怎么处理,也不要生吞异常,保留异常信息,把异常直接抛出去或构建新的异常再抛出去,更上层的业务代码可能会清楚合适的处理方式是什么
2.try-catch 代码段会产生额外的新能开销,会影响 JVM 对代码进行优化,建议只捕获有必要的代码段
3.Java 每实例化一个 Exception,都会对当时的栈进行快照,这是一个想对比较重的操作

三、经典题目

问:NoClassDefFoundError 和 ClassNotFoundException 有什么区别
NoClassDefFoundError:隐式装载类抛出的异常

如果 Java 虚拟机或类加载器实例试图装入类定义,但却没有找到类定义时抛出该异常,当前类已经完成编译过程,运行时找不到类定义,即在引用的类路径下没有找到当前类

ClassNotFoundException:显式装载类抛出的异常

如下所示,当应用程序试图通过字符串形式装载类,但却找不到指定类定义时抛出该异常
Class#forName()
ClassLoader#findSystemClass()
ClassLoader#loadClass()