Appearance
2026-08-27 · 程序出错时怎么处理——try-catch-finally、throws、自定义异常。
Java 异常处理
1. 异常是什么
程序运行时出错,Java 会抛出异常对象:
java
int[] arr = {1, 2, 3};
System.out.println(arr[5]); // ❌ ArrayIndexOutOfBoundsException不处理异常,程序会崩溃(打印红色堆栈信息然后终止)。
2. try-catch-finally
捕获异常,让程序继续运行:
java
try {
int[] arr = {1, 2, 3};
System.out.println(arr[5]); // 可能出错的代码
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("数组越界:" + e.getMessage()); // 处理异常
} finally {
System.out.println("无论是否出错都会执行"); // 可选
}
// 输出:
// 数组越界:Index 5 out of bounds for length 3
// 无论是否出错都会执行catch 可以捕多种异常:
java
try {
// 可能出多种错
} catch (ArithmeticException e) {
// 算术错误(除以零)
} catch (ArrayIndexOutOfBoundsException e) {
// 数组越界
} catch (Exception e) {
// 兜底:捕获所有其他异常
}catch 从上到下匹配,命中第一个就停。兜底的
Exception放最后。
try-with-resources(Java 7+):
java
// 自动关闭资源(文件、数据库连接等)
try (FileReader reader = new FileReader("test.txt")) {
// 使用资源
reader.read();
} // 自动调用 reader.close(),不用写 finally涉及 IO/数据库操作时,用 try-with-resources 更安全(不会忘记关闭)。
3. throws 与 throw
throws(声明可能抛出的异常)
java
// 方法声明可能抛出什么异常
public void readFile(String path) throws IOException {
FileReader reader = new FileReader(path); // 可能抛 IOException
reader.read();
}调用 throws 声明的方法时,必须处理异常(try-catch)或继续 throws。
throw(手动抛出异常)
java
public void setAge(int age) {
if (age < 0 || age > 150) {
throw new IllegalArgumentException("年龄不合法:" + age); // 手动抛出
}
this.age = age;
}throws vs throw:
| 区别 | throws | throw |
|---|---|---|
| 位置 | 方法签名上 | 方法体内 |
| 含义 | 声明"这个方法可能抛异常" | 手动"抛出一个异常" |
| 后面跟 | 异常类名 | 异常对象 |
4. 受检异常 vs 非受检异常
java
// 受检异常(Checked Exception):必须处理,编译器强制检查
try {
FileReader reader = new FileReader("不存在.txt"); // 编译报错!必须 try-catch 或 throws
} catch (FileNotFoundException e) {
// 处理
}
// 非受检异常(Unchecked Exception):运行时才报错,不强制处理
int[] arr = {1, 2, 3};
arr[5]; // 运行时才报 ArrayIndexOutOfBoundsException常见异常分类:
| 类型 | 常见异常 | 是否强制处理 |
|---|---|---|
| 受检异常 | IOException、FileNotFoundException、SQLException | ✅ 必须 |
| 非受检异常 | NullPointerException、ArrayIndexOutOfBoundsException、ClassCastException | ❌ 不强制 |
| 错误(Error) | OutOfMemoryError、StackOverflowError | ❌ 不处理(JVM 级别) |
日常开发中,受检异常用 try-catch 或 throws;非受检异常靠代码逻辑避免(判空、边界检查)。
5. 常见异常速查
java
NullPointerException // 空指针:对 null 调方法
ArrayIndexOutOfBoundsException // 数组越界
ClassCastException // 类型转换失败
NumberFormatException // 字符串转数字失败(Integer.parseInt("abc"))
IllegalArgumentException // 非法参数(手动抛出)
FileNotFoundException // 文件不存在遇到异常先看异常类名,它会告诉你出了什么问题。
6. 自定义异常
业务异常需要自己定义:
java
// 自定义受检异常
public class BusinessException extends Exception {
private int code;
public BusinessException(int code, String message) {
super(message);
this.code = code;
}
public int getCode() { return code; }
}
// 自定义非受检异常(更常用)
public class BusinessException extends RuntimeException {
private int code;
public BusinessException(int code, String message) {
super(message);
this.code = code;
}
public int getCode() { return code; }
}
// 使用
public void save(User user) {
if (user.getName() == null) {
throw new BusinessException(1001, "用户名不能为空");
}
}Spring Boot 项目里通常继承
RuntimeException(非受检),配合全局异常处理器@RestControllerAdvice统一返回错误信息。等学 Spring 再深入。