Java异常处理的核心是三层结构:Throwable为根,分Error(不可恢复,不捕获)和Exception;Exception再分RuntimeException(编程错误,优先修复而非捕获)和受检异常(必须try-catch或throws)。

Java异常处理不是背概念,而是理解“谁该在哪儿、用什么方式、说清楚什么事”。
先抓主干:Throwable 是根,底下分 Error 和 Exception;Exception 再分 RuntimeException(运行时异常)和受检异常(Checked Exception)。这个三层结构必须刻进本能——它决定了你写不写 try-catch、编译过不过、线上出问题时该往哪查。
明确每类异常的应对逻辑
- Error 不要 catch,比如 OutOfMemoryError 或 StackOverflowError。它们是 JVM 层崩溃信号,捕获了也救不回来,重点是调参、优化、监控预警。
- RuntimeException 是代码 Bug,比如 NullPointerException、ArrayIndexOutOfBoundsException。别急着 try-catch,先改逻辑:判空、校验索引、验证参数。捕获它,通常是兜底或日志记录,不是常态解法。
- 受检异常(IOException、SQLException 等)必须处理:要么 try-catch 吞掉并给出业务反馈,要么 throws 往上交。这是 Java 的契约设计——它强制你正视那些“大概率发生、但可恢复”的问题。
动手掌握核心语法与惯用模式
立即学习“Java免费学习笔记(深入)”;
-
try-with-resources代替手动 close:确保流、连接、文件句柄自动释放,避免资源泄漏。 - 多 catch 要按子类到父类顺序写,否则子类永远捕获不到。
-
finally不适合 return(会覆盖 catch 中的返回值),只做清理;真正要统一返回,用try-catch-return结构或封装工具方法。 - 抛异常时带上下文:
throw new BusinessException("订单创建失败", e),保留 cause 链,方便追溯原始根因。
进阶关键在分层治理
- Controller 层用
@ControllerAdvice全局捕获,转成标准 JSON 响应(带 error code、message、traceId),绝不暴露堆栈给前端。 - Service 层抛业务异常(自定义 BusinessException),不抛技术异常(如 SQLException)。
- DAO 层捕获具体技术异常,转换为语义清晰的业务异常,屏蔽数据库细节。
- 日志里记全:方法名、入参、错误码、cause.getMessage()、甚至关键业务字段,别只写“发生异常”四个字。
本质上,学异常处理就是学怎么让程序既不崩、又说得清、还能快速修。不靠死记,靠在每次 throw 和 catch 时多问一句:“这异常是谁的责任?现在处理合适吗?下游需要知道什么?”


















