异常
理解异常的体系与分类
掌握 try-catch-finally 异常处理
学会抛出异常与自定义异常
核心讲解
(1)异常体系
Throwable 是根,分两大类:
Error:严重错误,比如 OOM,程序处理不了
Exception:异常,程序可以处理
运行时异常 RuntimeException:编译不检查,比如空指针、数组越界
检查异常 CheckedException:编译必须处理,比如 IO 异常、SQL 异常
(2)异常处理 try-catch-finally
try {
// 可能出错的代码
} catch (异常类型 e) {
// 捕获到异常的处理
} finally {
// 无论是否异常,最后一定执行,释放资源
}
可以多个 catch,从小到大写
finally 一定会执行,哪怕 try 里有 return
只有 System.exit (0) 能让 finally 不执行
(3)抛出异常
throw:方法内部抛出异常对象throws:方法声明上,声明这个方法可能抛出异常,调用者处理
(4)自定义异常
继承 Exception(检查异常)或者 RuntimeException(运行时异常),一般继承 RuntimeException。
代码示例
// 自定义异常
class AgeException extends RuntimeException {
public AgeException(String message) {
super(message);
}
}
public class ExceptionDemo {
public static void main(String[] args) {
// ===== try-catch =====
try {
int[] arr = {1, 2, 3};
System.out.println(arr[5]); // 数组越界
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("捕获到数组越界异常:" + e.getMessage());
e.printStackTrace(); // 打印堆栈信息
} finally {
System.out.println("finally一定会执行");
}
// ===== 方法抛出异常 =====
try {
setAge(150);
} catch (AgeException e) {
System.out.println("年龄异常:" + e.getMessage());
}
}
// 方法声明抛出异常
public static void setAge(int age) throws AgeException {
if (age < 0 || age > 120) {
// 抛出异常
throw new AgeException("年龄不合法:" + age);
}
System.out.println("年龄设置成功:" + age);
}
}
常见误区
异常捕获了不处理:空 catch 块,等于把错误藏起来,排查问题非常困难
finally 里写 return:finally 里的 return 会覆盖 try 里的返回值,非常坑
抛出 Exception 太宽泛:尽量抛出具体的异常类型,不要直接抛 Exception
用异常控制业务流程:异常是处理错误的,不要用来做正常业务逻辑
课后练习
编写一个除法方法,捕获除零异常
自定义一个用户名不能为空的异常
写一个登录方法,用户名空的时候抛出自定义异常
说明 final、finally、finalize 的区别

