Java中Exception 和 Error 的区别

Java中Exception 和 Error 的区别

文章目录

经典回答:

Exception 和 Error 都是继承了 Throwable 类,在 Java 中只有 Throwable 类型的实例才可以被抛出(throw)或者捕获(catch),它是异常处理机制的基本组成类型。

Exception 和 Error 体现了 Java 平台设计者对不同异常情况的分类。Exception 是程序正常运行中,可以预料的意外情况,可能并且应该被捕获,进行相应处理。

Error 是指在正常情况下,不大可能出现的情况,绝大部分的 Error 都会导致程序(比如 JVM自身)处于非正常的、不可恢复状态。既然是非正常情况,所以不便于也不需要捕获,常见的比如 OutOfMemoryError 之类,都是 Error 的子类。

Exception 又分为检查型(checked)异常和非检查型(unchecked)异常,检查型异常在源代码里必须显式地进行捕获处理,这是编译期检查的一部分。

非检查型异常就是所谓的运行时异常,均继承于RuntimeException,类似 NullPointerException、ArrayIndexOutOfBoundsException 之类,通常是可以编码避免的逻辑错误,具体根据需要来判断是否需要捕获,并不会在编译期强制要求。

Exception 和 Error 举例

Java中Exception 和 Error 的区别

备注:

1. NoClassDefFoundError 和 ClassNotFoundException 的区别:

NoClassDefFoundError: 编译成功后,执行程序时Class被删除报此错误
ClassNotFoundException: 动态加载Class如:Class.forName()、ClassLoader.loadClass()时,发现Class不存在,则会抛出此异常。

2. 为什么RuntimeException及其子类是非检查型异常,RuntimeException 不也是继承自Exception吗?

RuntimeException 这类异常在编译器层面进行了特殊处理,参考自 资料2。

关于异常使用过程中需要注意的几点

  1. 可以使用 try-with-resources 和 multiple catch 减少代码,但是可能实际上编译后的代码更加啰嗦;
  2. 尽量不要捕获类似Exception这样的通用异常,而应该捕获代码实际上会抛出的异常;
  3. 不要生吞异常,即捕获异常后,既不输出也不进行处理;
  4. 由于 e.printStackTrace() 是输出到标准错误流中,在大型系统中,很难判断到底是输出到哪儿去了,所以最好是详细输出到日志系统中;
  5. Throw early, catch late 原则,尽可能早的抛出异常避免堆栈信息过长,从而无法快速定位问题;catch late 指的是当下捕获异常后难以进行业务或逻辑上的处理,可以将其继续往上抛,在更高层因为业务、逻辑更清晰,会更便于处理;
  6. 关于 checkedException 和 RuntimeException 的选择
    个人理解:checkException 更像是大概率、客观上可能会出现的异常;而RuntimeExceptin则更像是小概率、主观上(例如1/0、数组越界等)可能出现的异常;
    官方解释:checkedException 是指异常发生后可以恢复程序,RuntimeException 是指异常发生后,无法恢复;
  7. 关于try catch 对性能的影响,实际上是:可能会抑制JVM对try里面代码的优化,这里的性能影响应该是非常小的;而更有影响的应该是抛出异常时,由于JVM需要保存方法调用的堆栈信息,此处性能更为消耗性能,特别是在抛出异常较多时。

PS:《Java核心技术36讲》第二讲读书笔记

参考资料:

  1. https://*.com/questions/16451777/is-it-expensive-to-use-try-catch-blocks-even-if-an-exception-is-never-thrown?tdsourcetag=s_pctim_aiomsg
  2. https://*.com/questions/11547914/why-runtime-exception-is-unchecked-exception
上一篇:java——异常与捕获


下一篇:【想进阿里的小菜鸟】C程序经典100例 No.7