「这是我参与11月更文挑战的第3天,活动详情查看:2021最后一次更文挑战」。
什么是异常
在Java中,异常可以看做是导致程序无法正常运行的事件,常见的异常有NullPointerException,IndexOutOfBoundsException,OutOfMemoryError等等。这些事件可能发生在编译期,也可能发生在运行时。
Java异常继承层次结构如下图所示:
需要指出的是,这里所说的异常,并不单单指Exception,还包括Error,二者都继承了Throwable类。
Exception和Error有什么不同呢?简单地说,Exception是可以通过编写代码来进行处理的,使得程序可以继续执行下去;而Error是无法通过代码来进行处理的。举个例子,Exception中像最常见的NullPointerException,通过try-catch语句对异常进行捕获后,程序是可以继续运行下去的;而Error中常见的OutOfMemoryError,StackOverflowError等,当它们发生时,是无法使用代码处理、使得程序继续运行下去的。
Exception又可以进一步划分为Checked Exception和RuntimeException。Checked Exception发生在编译期,必须用代码显式地进行处理,否则无法通过编译。最常见的例子是在打开文件时需要用try-catch来捕获异常。而RuntimeException发生在运行时,不需要用代码显式地处理,最常见的是NullPointerException。
Exception处理
try-catch-finally
try-catch-finally基本使用如下所示:
try {
// Protected code
} catch (ExceptionType e) {
// Catch block
} finally {
// The finally block always executes.
}
Protected code代表可能会抛出Exception的代码,ExceptionType表示我们想要捕获的Exception类型,Catch block代表对异常的处理代码,finally中的代码总会执行,常用来释放资源。
如果想捕获多个异常,可以用下面的代码:
try {
// Protected code
} catch (ExceptionType1 e1) {
// Catch block
} catch (ExceptionType2 e2) {
// Catch block
} catch (ExceptionType3 e3) {
// Catch block
}finally {
// The finally block always executes.
}
throws & throw
如果一个方法没有捕获到一个检查性异常或者throw抛出的异常,那么该方法必须使用 throws 关键字来声明。throws 关键字放在方法签名的尾部。
import java.io.*;
public class className {
public void deposit(double amount) throws RemoteException {
// Method implementation
throw new RemoteException();
}
// Remainder of class definition
}
自定义异常
如果要自定义Checked Exception,那么类需要继承Exception;如果要自定义runtime exception,那么类需要继承RuntimeException。一个checked Exception的例子如下:
public class InsufficientFundsException extends Exception {
private double amount;
public InsufficientFundsException(double amount) {
this.amount = amount;
}
public double getAmount() {
return amount;
}
}