通过一张图来展示Throwable类的继承体系,如图2所示。
图2 Throwable异常体系结构图
● Error类称为错误类,它表示Java运行时产生的系统内部错误或资源耗尽的错误,是比较严重的,仅靠修改程序本身是不能恢复执行的,例如系统崩溃,虚拟机错误等。
● Exception类称为异常类,它表示程序本身可以处理的错误。在Java程序开发中进行的异常处理,都是针对Excption类及其子类的。在Exception类的众多子类中有一个特殊的RuntimeException类,该类及其子类用于表示运行时异常。除了此类,Exception类下所有其他的子类都用于表示编译时异常。
表1 Throwable常用方法
方法声明 | 功能描述 |
String getMessage() | 返回此throwable的详细消息字符串 |
void printStackTrace() | 将此throwable及其追踪输出至标准错误流 |
void printStackTrace(PrintStream s) | 将此throwable及其追踪输出到指定的输出流 |
异常的类型
处理编译时异常有两种方式,具体如下:
● 使用try…catch语句对异常进行捕获处理;
● 使用throws关键字声明抛出异常,让调用者对其处理。
1.编译时异常
在Exception的子类中,除了RuntimeException类及其子类外,其他子类都是编译时异常。
2.运行时异常
RuntimeException类及其子类都是运行时异常。
表1 常见运行时异常
异常类名称 | 异常类说明 |
ArithmeticException, | 算术异常 |
IndexOutOfBoundsException | 角标越界异常 |
ClassCastException | 类型转换异常 |
NullPointerException | 空指针异常 |
NumberFormatException | 数字格式化异常 |
try...catch和finally
ry{}代码块中包含的是可能发生异常的语句,catch(){}代码块中编写针对捕获的异常进行处理的代码。
需要注意的是,在try{}代码块中,发生异常语句后面的代码是不会被执行的。
有时候会希望有些语句无论程序是否发生异常都要执行,这时就可以在try…catch语句后,加一个finally{}代码块。
throws关键字
在前面章节案例中,定义除法运算时,开发者通常会意识到可能出现的异常,可以直接通过try...catch对异常进行捕获处理,但有些时候,方法中代码是否会出现异常,开发者并不明确或者并不急于处理,为此,Java允许将这种异常从当前方法中抛出,然后让后续的调用者在使用时再进行异常处理。
throw关键字
与throws有所不同的是,throw用于方法体内,并且抛出的是一个异常类对象,而throws关键字用在方法声明中,用来指明方法可能抛出的多个异常。
通过throw关键字抛出异常后,还需要使用throws关键字或try…catch对异常进行处理。需要注意的是,如果throw抛出的是Error、RuntimeException或它们的子类异常对象,则无需使用throws关键字或try…catch对异常进行处理。
自定义异常
// 下面的代码是自定义一个异常类继承自Exception
public class DivideByMinusException extends Exception{
public DivideByMinusException (){
super(); // 调用Exception无参的构造方法
}
public DivideByMinusException (String message){
super(message); // 调用Exception有参的构造方法
}
}
public class Example36 {
// 下面的方法实现了两个整数相除,
public static int divide(int x,int y) throws DivideByMinusException {
if (y == 0) {
// 使用throw关键字声明异常对象
throw new DivideByMinusException("除数是0");
}
int result = x / y; // 定义一个变量result记录两个数相除的结果
return result; // 将结果返回
}
public static void main(String[] args) {
try {
int result = divide(4, 0);
System.out.println(result);
} catch (DivideByMinusException e) {
System.out.println("捕获的异常信息为:" + e.getMessage());
}
}
}