Exception & Error 运行时异常 & 一般异常

长得一样怎么实际上天差地别 🦹‍♀️

Author: Corissa

Date: Dec.28 2023

重点需要掌握🏁:

理解 Throwable, Exception, Error 的设计和分类

掌握常见的子类,知道如何自定义异常

掌握实操中的元素和语法 (try-catch-finally, try-with-resource, multiple catch, throw, throws, AutoCloseable, Closeable )

1 对比分析

Error & Exception 相同点

二者都继承了 Throwable 类,只有这个类型的实例才能被抛出 (throw) 或者捕获 (catch)。

他们是异常处理机制的基本组成类型。

源码中对 Throwable 类的描述如下:

The Throwable class is the superclass of all errors and exceptions in the Java language. Only objects that are instances of this class (or one of its subclasses) are thrown by the JVM or can be thrown by the Java throw statement. Similarly, only this class or one of its subclasses can be the argument type(参数类型) in a catch clause.

Error & Exception 不同点

本质上 Exception 和 Error 是 Java 平台对不同异常情况的分类。

Exception:

程序正常运行中可以预料到的异常情况,可能并且应当尽快被捕获,并进行相应处理。异常处理可以保证出现异常后由我们的程序决定接下来的程序流程,比如定位异常位置,避免程序崩溃等等。

异常也分为可检查 (checked) 异常和不检查 (unchecked) 异常,不检查异常也即运行时 (runtime) 异常。

Checked Exception: 没有继承RuntimeException类,需要 coding 时对该异常进行显示的捕获,是编译期检查的一部分。

​ - 编译器对可检查异常的处理要求:

​ 1. try-catch 捕获 2. 不断向上抛出交给 JVM 处理

​ - 举例:FileNotFoundExcption, IOException

Runtime Exception: 继承了RuntimeException类,大部分是逻辑问题,不会在编译期强制进行捕获。

​ - 编译器对运行时异常的处理要求:

​ 1. try-catch 捕获 2. 不断向上抛出 3. 不处理

​ - 举例:NullPointerException, ArrayIndexOutOfBoundsException

Error:

程序正常情况下不大可能出现的情况,且绝大多数 Error 会导致程序处于非正常、不可恢复的状态,这种情况下不便于也不需要捕获。

举例:OutOfMemoryError、NoClassDefFoundError、VirtualMachineError、StackOverflowError

exception&error relation

2.2 拓展

2.2.1 一些原则
  1. 尽量不要捕获类似 Exception 这样的通用异常,而是捕获具体异常
  2. 不要生吞 (swallow) 异常
  3. Throw early catch late
2.2.2 一些拓展知识点总结
  • throw& throws

    • Throws 写在方法头,throw 是写在方法内的语句
    • Throws 能一次抛出多个异常,throw一次只能抛出一个
    • throws抛出异常,其调用者也要申明抛出异常或者捕获异常;而 throw 调用者可以不声明不捕获
    1
    2
    3
    4
    5
    6
    //throws
    修饰符 返回类型 方法名(参数列表) throws 异常列表 {
    // 方法体
    }
    //throw
    throw new 异常类名称(构造函数参数);
  • close & AutoCloseable & Closeable

    • AutoCloseable 和 Closeable 是接口,close() 是规定实现此类必须实现的方法

    • AutoCloseable 和 Closeable 都用于 try-with-resource 模块中

    • AutoCloseable 的 close() 继承了 Exception 接口

      Closeable 的 close() 继承了 IOException 接口

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      public class demo implements Closeable {
      @Override
      public void close() throws IOException {

      }
      }

      public class demo implements AutoCloseable {
      @Override
      public void close() throws Exception {

      }
      }
    • 建议实现者在声明关闭方法的具体实现时抛出更具体的异常,或者在关闭操作不会失败的情况下不抛出异常。

    • 对于关闭操作可能失败的情况,实现者需要谨慎处理。强烈建议在抛出异常之前放弃底层资源,并在内部将资源标记为已关闭。关闭方法不太可能被多次调用,因此这能确保及时释放资源。此外,它还能减少资源被其他资源包装或包裹时可能出现的问题。
      我们还强烈建议该接口的实现者不要让 close 方法抛出 InterruptedException(中断异常)。这种异常会与线程的中断状态发生交互,如果抑制 InterruptedException,运行时可能会发生错误行为。一般来说,如果抑制异常会导致问题,AutoCloseable.close 方法就不应抛出异常。

2.2.3 problems tbc…🐕

2.2.2最后两点是官方给出的建议,应当结合gc机制再次学习

有空再次对try-catch-finally, try-with-resource, multiple catch进行总结复习