Java异常机制

Java异常机制,是程序运行不正常时的处理方式。具体来说,异常机制提供了程序安全退出的通道。当异常发生时,程序的执行流程改变,程序控制权转移到异常处理器

一、Java异常继承体系

Java异常类的继承体系如下图所示:

Throwable类是整个Java异常体系的超类,包括错误Error和异常Exception两个子类。

  • Error表示程序在运行期间出现了十分严重、不可恢复的错误,这种情况下应用程序只能终止运行,比如JVM出现错误(VirtualMachineError)。应用程序一般不捕获Error,因为它是应用程序所无法处理的情况。
  • Exception是应用程序可以处理的异常,可以选择对其进行捕获并处理,包含运行时异常(RuntimeException)非运行时异常(除RuntimeException外的其他异常)
    • 运行时异常RuntimeException是在程序运行时出现的异常,一般是由程序的逻辑错误所引起的,可以选择捕获处理,也可以不捕获处理。比如NullPointerException、IndexOutOfBoundsException等。
    • 非运行时异常也叫受检异常必须在应用程序中对其进行捕获处理或者向上抛出,否则无法通过编译器检查。比如IOException、ClassNotFoundException等。方法内部如果抛出了受检异常,则必须在方法头部声明抛出该受检异常类型。

用户可以在在Java异常体系的基础上自定义类异常类型,自定义异常类型要遵循以下原则:

  • 自定义异常类必须是Throwable的子类。
  • 如果想自定义一个受检异常类,需要继承Exception类
  • 如果想自定义一个运行时异常类,需要继承RuntimeException类

二、异常的抛出与捕获处理

1.异常抛出(throw、throws)

throw关键字用于方法体内部,用来抛出异常。如果抛出的是一个受检异常,那么还应该在方法头部用throws声明抛出的受检异常类型,该方法的调用者也必须捕获处理或者向上抛出这个受检异常。比如:

public class className {
public void deposit(double amount) throws RemoteException {
// Method implementation
throw new RemoteException();
}
//Remainder of class definition
}

2.异常捕获处理(try…catch…finally)

try代码块中某位置抛出了异常,则该位置之后的代码再也没有机会被执行。

catch可以有多个,一个try代码块后面跟随多个catch代码块的情况叫多重捕获,根据异常的类型从上往下匹配,如果有匹配的catch,下面的所有catch会被全部忽略。

多重捕获下要先catch子类异常再catch父类异常,即子类异常的catch块在父类异常catch块的上面。如果顺序反了的话,那么根据Java继承思想,所有子类异常对象都是父类异常对象,导致父类异常永远先被捕获到,而捕获子类异常的catch块永远得不到执行,出现编译错误。比如下面的代码:(ArithmeticException是Exception的子类,属于受检异常)

public class ExceptionErrorDemo {
public static void main(String[] args) {
int[] numbers = new int[3];
try {
numbers[0] = 1;
numbers[1] = 3;
numbers[2] = 7;
numbers[3] = numbers[2] / 0;//会抛出算术运算异常;
} catch (Exception e) {
System.out.println(e.toString());
} catch (ArithmeticException e) {
e.toString();
}
}
}

无论try代码块中是否发生异常,finally代码块都会被执行。通常可以在finally块中进行资源的回收工作,比如关闭打开的文件、删除临时文件等。

如果try、catch块中有return语句,会先把返回值压栈,然后再执行finally语句,执行完finally语句后再返回。即使在finally中更改了要返回的变量的值,程序依然会返回之前已经压栈的值,而不是在finally中更新后的值。当然,如果try、catch中返回的变量是一个对象引用而非基本类型,由于引用已经压栈无法更改,可以通过在finally块中更改引用指向的对象的内容,来影响返回结果。如果finally中有return语句,那么直接忽略try、catch中的return语句,只执行finally的return

文章作者: Moon Lou
文章链接: https://loumoon.github.io/2021/03/12/Java异常机制/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Moon's Blog