Java 异常处理
程序运行时难免出错:除零、数组越界、文件不存在。若错误直接让程序崩溃就太糟了,Java 的异常机制让错误能被“抛出”、被“捕获”后优雅处理。
异常体系
所有异常的根是 Throwable,分两类:Error(系统级严重错误如内存溢出,程序无法处理)与 Exception(程序可处理)。Exception 又分检查异常(IOException、SQLException,编译期强制 try-catch 或 throws)和运行时异常 RuntimeException(NullPointerException、ArithmeticException 等,不强制声明但最好预防)。
try-catch-finally 与多重 catch
try 放可能出错的代码,catch 捕获异常,finally 无论是否异常都执行;多个 catch 从上往下匹配第一个,所以子类在前、父类在后:
// 片段需放进 main 方法中运行
try {
int r = 10 / 0; // 除零
} catch (ArithmeticException e) {
System.out.println("除零:" + e.getMessage()); // 输出:除零:/ by zero
} finally {
System.out.println("finally 总会执行"); // 输出:finally 总会执行
}
try {
Integer.parseInt("abc"); // 多重 catch 示例
} catch (NumberFormatException e) {
System.out.println("格式错误"); // 输出:格式错误
} catch (Exception e) { // 宽泛的放后面
System.out.println("其他异常");
}
try-with-resources 自动关闭
实现了 AutoCloseable 的资源写在 try 括号里,代码块结束自动 close()(正常返回或抛异常都一样),不用手写 finally:
// 片段需放进 main 方法中运行(先 import java.io.*)
try (BufferedReader br = new BufferedReader(new FileReader("a.txt"))) {
System.out.println(br.readLine());
} catch (IOException e) {
System.out.println("读取失败:" + e.getMessage());
}
throw 与 throws
throw 在方法体内主动抛出异常对象;throws 写在方法签名上,声明本方法可能抛出检查异常,把处理责任交给调用者:
// 片段:方法需放在某个类中,调用代码放进 main
static void checkAge(int age) throws Exception { // throws 声明
if (age < 0) {
throw new Exception("年龄不能为负数"); // 主动抛出
}
System.out.println("年龄合法:" + age);
}
// try { checkAge(-1); } catch (Exception e) {
// System.out.println(e.getMessage()); // 输出:年龄不能为负数
// }
自定义异常
业务错误(如余额不足)可以自定义异常表达:继承 RuntimeException 或 Exception,并提供带消息的构造方法:
class BalanceNotEnoughException extends RuntimeException {
BalanceNotEnoughException(String message) {
super(message);
}
}
class Account {
double balance;
void withdraw(double money) {
if (money > balance) throw new BalanceNotEnoughException("余额不足:" + balance);
balance -= money;
}
}
public class CustomDemo {
public static void main(String[] args) {
Account a = new Account();
try {
a.withdraw(100);
} catch (BalanceNotEnoughException e) {
System.out.println(e.getMessage()); // 输出:余额不足:0.0
}
}
}
常见异常与规避
NullPointerException 先判空再用;ArrayIndexOutOfBoundsException 先看数组 length;ClassCastException 先 instanceof 判断;ArithmeticException 先判断除数是否为 0。
小结:Throwable 之下 Error 不可处理、Exception 要处理;检查异常编译期强制、运行时异常靠预防;用 try-with-resources 关资源,用自定义异常表达业务错误。