一、异常核心体系(类结构+分类)
1. 顶层类结构
- 根类: Throwable (所有错误和异常的父类)
- 子类1: Error (系统级错误,如 OutOfMemoryError 、 StackOverflowError )→ 程序无法处理,直接终止,无需捕获。
- 子类2: Exception (程序级异常,可通过代码处理)→ 核心关注对象。
2. Exception 分类(高频考点)
表格
类型 特点 常见示例 处理要求
检查型异常(Checked) 编译时强制要求处理(继承 Exception ,非 RuntimeException ) IOException 、 SQLException 、自定义业务异常 必须用 try-catch 捕获或 throws 声明
非检查型异常(Unchecked) 运行时触发(继承 RuntimeException ) NullPointerException 、 ArrayIndexOutOfBoundsException 、 ArithmeticException 可选处理,编译不报错
二、核心关键字与执行流程
1. 四大关键字用法
- try :包裹可能触发异常的代码块,不可单独使用,需搭配 catch / finally 。
- catch :捕获指定异常并处理,可多个 catch 并列(子类异常在前,父类异常在后),JDK 7+支持多异常合并( | 分隔)。
- finally :无论是否捕获异常,必执行(仅 System.exit(0) 强制终止JVM时不执行),常用于关闭资源(如流、连接)。
- throw vs throws :
- throw :方法内主动触发异常(如 throw new NullPointerException("空指针") )。
- throws :方法声明处标注可能抛出的异常,告知调用者需处理(如 public void read() throws IOException )。
2. 异常执行流程(关键逻辑)
1. 执行 try 块,若触发异常,立即跳出 try ,匹配首个兼容的 catch 块。
2. 若未找到匹配 catch ,异常向上抛出,直至JVM默认处理(打印堆栈+终止程序)。
3. 无论是否捕获异常,最终执行 finally 块(若存在)。
4. 若 try / catch 中有 return , finally 执行后才返回( finally 中修改返回值会覆盖原结果,禁止此操作)。
三、JDK 7+ 新特性(实战重点)
1. 多异常合并捕获
2. try-with-resources(自动资源关闭)
- 适用场景:处理实现 AutoCloseable 接口的资源(如 FileReader 、 Connection 、 InputStream )。
- 优势:自动关闭资源,无需手动在 finally 处理,避免资源泄露。
四、自定义异常(实战规范)
1. 实现步骤
(1). 继承 Exception (检查型)或 RuntimeException (非检查型)。
(2). 提供构造方法(无参、带异常信息、带异常信息+原始异常),传递异常根源。
2. 选型原则
- 业务核心异常(如登录失败、数据校验失败)→ 继承 Exception (检查型),强制调用者处理。
- 编程错误(如参数为空)→ 继承 RuntimeException (非检查型),无需强制声明。
五、异常处理最佳实践(避坑重点)
1. 精准捕获:避免 catch (Exception e) {} 泛化捕获,优先捕获具体异常(如 NullPointerException )。
2. 不吞异常:捕获后需处理(日志记录、返回错误信息),禁止空 catch 块。
3. 保留异常链:抛出新异常时,传递原始异常( super(message, cause) ),便于调试。
4. 资源关闭优先用 try-with-resources:替代 finally 手动关闭,避免遗漏 close() 异常。
5. finally 禁止做这些事:不修改返回值、不抛出新异常、不执行 System.exit(0) 。
6. 方法重写的异常规则:子类重写父类方法时,抛出的异常不能超出父类方法声明的异常范围(可少抛、不抛,不能多抛父类未声明的检查型异常)。
六、高频考点与易错点
1. 经典面试题
- Q1: Error 和 Exception 的区别?→ 前者系统级错误(不可处理),后者程序级异常(可处理)。
- Q2:检查型异常和非检查型异常的区别?→ 编译时是否强制处理,继承关系不同。
- Q3: finally 一定执行吗?→ 仅 System.exit(0) 强制终止JVM时不执行。
- Q4: try-catch-finally 中 return 的执行顺序?→ try / catch 的 return 先入栈,执行 finally 后,返回栈中值( finally 修改返回值会覆盖)。
2. 易错点案例
- 错误: catch (Exception e) { throw new MyException("错误"); } (丢失原始异常链)
- 正确: catch (Exception e) { throw new MyException("错误", e); } (保留根源)
- 错误: finally { return 2; } (覆盖 try 中的 return 1 ,返回2)
- 正确:不在 finally 中写 return 。
8万+

被折叠的 条评论
为什么被折叠?



