概念
异常处理的概念起源于早期的编程语言,如 LISP、PL/I 和 CLU。这些编程语言首次引入了异常处理机制,以便在程序执行过程中检测和处理错误情况。异常处理机制随后在 Ada、Modula-3、C++、Python、Java 等编程语言中得到了广泛采用和发展。在 Java 中,异常处理是提供一种在程序运行时处理错误和异常情况的方法。异常处理机制使得程序能够在遇到错误时继续执行,而不是立即崩溃。这种机制使程序更具有健壮性和容错性。异常分为两类:受检异常(Checked Exceptions)和非受检异常(Unchecked Exceptions)
受检异常(Checked Exceptions):
受检异常是指那些在编译时必须处理的异常。它们通常是由程序员的错误或外部资源问题引起的。例如,IOException
、FileNotFoundException
等。受检异常必须在方法签名中使用 throws
关键字声明,或者在方法体内用 try-catch
块捕获和处理。
非受检异常(Unchecked Exceptions):
非受检异常是指那些在编译时不强制要求处理的异常。它们通常是由编程错误引起的,如空指针异常(NullPointerException
)、数组越界(ArrayIndexOutOfBoundsException
)等。非受检异常继承自 java.lang.RuntimeException
类,不需要在方法签名中声明,也不需要强制捕获和处理。
它们的关系如下:
异常处理
Java 使用 try/catch
关键字进行异常捕获,使用 throw
声明抛出异常,示例代码如下:
public class NullPointerExceptionExample {
public static void main(String[] args) {
String nullString = null;
try {
int length = nullString.length();
} catch (NullPointerException e) {
System.out.println("Caught NullPointerException!");
e.printStackTrace();
}
}
}
在这个示例中,我们尝试获取一个 null
字符串的长度。当调用 nullString.length()
时,会抛出 NullPointerException
。我们使用 try-catch
语句捕获异常并处理它
自定义异常
Java 官方异常不可能预见所有可能发生的错误,有时候你需要结合自己的业务场景,例如以下场景:
- 当内置的 Java 异常类无法准确描述你所遇到的异常情况时。
- 需要为特定领域或业务逻辑创建一组特定的异常。
- 当希望通过自定义异常类向调用者提供更多的上下文信息或特定的错误代码时。
构建特定的异常,这也很简单,继承已有的异常类(最好继承含义差不多的),如下,我们创建一个表示账户余额不足的异常:
public class InsufficientBalanceException extends RuntimeException {
private double balance;
private double amount;
public InsufficientBalanceException(double balance, double amount) {
super("Insufficient balance: " + balance + ", required amount: " + amount);
this.balance = balance;
this.amount = amount;
}
public double getBalance() {
return balance;
}
public double getAmount() {
return amount;
}
}
接下来,我们在业务逻辑代码中使用这个自定义异常:
public class BankAccount {
private double balance;
public BankAccount(double balance) {
this.balance = balance;
}
public void withdraw(double amount) throws InsufficientBalanceException {
if (amount > balance) {
throw new InsufficientBalanceException(balance, amount);
}
balance -= amount;
}
}
调用者可以捕获并处理这个自定义异常:
public class BankAccountTest {
private static final Logger logger = Logger.getLogger(BankAccountTest.class.getName());
public static void main(String[] args) {
BankAccount account = new BankAccount(1000.00);
try {
account.withdraw(2000.00);
} catch (InsufficientBalanceException e) {
System.out.println("Error: " + e.getMessage());
System.out.println("Current balance: " + e.getBalance());
System.out.println("Required amount: " + e.getAmount());
logger.log(Level.SEVERE, "An exception