1. Java 异常类层次结构图

file

file

在 Java 中,所有的异常都有⼀个共同的祖先java.lang包中的Throwable类。Throwable类有两个重要的⼦类Exception(异常)和Error(错误)。Exception能被程序本身处理(try-catch),Error是⽆法处理的(只能尽量避免)。

ExceptionError⼆者都是 Java 异常处理的重要⼦类,各⾃都包含⼤量⼦类。

  • Exception:程序本身可以处理的异常,可以通过catch来进⾏捕获。Exception⼜可以分为受检查异常(必须处理)和不受检查异常(可以不处理)。
  • ErrorError属于程序⽆法处理的错误,我们没办法通过catch来进⾏捕获。例如,Java 虚拟机运⾏错误(VirtualMachineError)、虚拟机内存不够错误(OutOfMemoryError)、类定义错误(NoClassDefFoundError)等。这些异常发⽣时,Java虚拟机(JVM)⼀般会选择线程终⽌。

受检查异常

Java 代码在编译过程中,如果受检查异常没有被catch/throw处理的话,就没办法通过编译。⽐如下⾯这段 IO 操作的代码。

class Example {
    public static void main(String args[]) throws IOException {
        FileInputStream fis = null;
        fis = new FileInputStream("B:/myfile.txt");
        int k;

        while ((k = fis.read()) != -1) {
            System.out.print((char) k);
        }
        fis.close();
    }
}

除了RuntimeException及其⼦类以外,其他的Exception类及其⼦类都属于受检查异常。常⻅的受检查异常有:IO 相关的异常、ClassNotFoundExceptionSQLException···

不受检查异常

Java 代码在编译过程中,我们即使不处理不受检查异常也可以正常通过编译。RuntimeException及其⼦类都统称为⾮受检查异常,例如:NullPointExecrptionNumberFormatException(字符串转换为数字)、ArrayIndexOutOfBoundsException(数组越界)、ClassCastException(类型转换错误)、ArithmeticException(算术错误)等。

2. Throwable 类常⽤⽅法

  • public string getMessage(): 返回异常发⽣时的简要描述
  • public string toString(): 返回异常发⽣时的详细信息
  • public string getLocalizedMessage(): 返回异常对象的本地化信息。使⽤Throwable的⼦类覆盖这个⽅法,可以⽣成本地化信息。如果⼦类没有覆盖该⽅法,则该⽅法返回的信息与getMessage() 返回的结果相同
  • public void printStackTrace(): 在控制台上打印Throwable对象封装的异常信息

3. 异常处理总结

try块:⽤于捕获异常。其后可接零个或多个catch块,如果没有catch块,则必须跟⼀个finally块。
catch块:⽤于处理try捕获到的异常。
finally块:⽆论是否捕获或处理异常,finally块⾥的语句都会被执⾏。当在try块或catch块中遇到return语句时,finally语句块将在⽅法返回之前被执⾏。

在以下 3 种特殊情况下,finally块不会被执⾏:

  1. tryfinally块中⽤了System.exit(int)退出程序。但是,如果System.exit(int)在异常语句之后,finally还是会被执⾏
  2. 程序所在的线程死亡。
  3. 关闭 CPU。

注意:当try语句和finally语句中都有return语句时,在⽅法返回之前,finally语句的内容将被执⾏,并且finally语句的返回值将会覆盖原始的返回值。如下:

public static int f(int value) {
    try {
        return value * value;
    } finally {
        if (value == 2) {
            return 0;
        }
    }
}

如果调⽤f(2),返回值将是 0,因为finally语句的返回值覆盖了try语句块的返回值。

最后修改日期: 2021年11月22日

留言

撰写回覆或留言

发布留言必须填写的电子邮件地址不会公开。