java多重catch需按具体到宽泛顺序排列子类在前、父类在后;可合并无继承关系异常类型;日志须含业务上下文并脱敏;spring项目优先用@controlleradvice全局处理。

Java 中多重 catch 块通过在同一个 try 后面声明多个 catch 子句,按顺序匹配并处理不同类型的异常。关键在于类型精确性、顺序合理性和逻辑清晰性——不是堆砌 catch,而是让每种异常得到恰当响应。
多个独立 catch 块:按具体到宽泛排列
这是最常用也最推荐的方式,适合各类异常需要差异化处理的场景。
- 每个 catch 块只声明一种异常类型,JVM 从上到下依次比对,命中第一个兼容类型即执行
- 子类异常必须写在父类前面,否则编译失败。例如 NullPointerException 要放在 RuntimeException 之前,SQLException 要放在 Exception 之前
- 避免把 Exception 或 Throwable 放在靠前位置,否则它会“遮蔽”所有后续 catch
单个 catch 捕获多种异常:用竖线(|)合并语义相近类型
Java 7 起支持在同一 catch 中用 | 分隔多个互不继承的异常类型,适用于处理逻辑完全一致的情况。
- 写法示例:
catch (IOException | SQLException e) - 被合并的异常不能有继承关系(如不能写
FileNotFoundException | IOException),否则编译报错 - 异常参数 e 是隐式 final 的,不可重新赋值
- 适合统一记录日志、返回通用错误码等场景,但不适合需区分原因做不同恢复动作的情形
业务日志中带上下文字段,别只记 e.getMessage()
捕获异常后若只打印简单信息,排查效率极低。真正有用的错误日志必须包含业务上下文。
- 至少包括:当前操作(如 "pay_order")、用户 ID、请求 traceId、异常类名、截断后的消息(建议 ≤200 字)
- 敏感内容如密码、token、原始 SQL 必须脱敏,可用正则替换或白名单过滤
- 避免直接调用
e.printStackTrace();应使用日志框架的logger.error(msg, e)让堆栈自动附加 - 不要在每个 catch 里重复写日志逻辑,封装成工具方法,传入异常和业务参数即可
Spring 项目优先用 @ControllerAdvice,少写手动 try-catch
在 Web 层硬编码大量 try-catch 是反模式。Spring 提供了更优雅、可复用的全局异常处理机制。
- 定义 @ControllerAdvice 类,配合 @ExceptionHandler 方法集中拦截指定异常
- 自定义业务异常基类(如 BusinessException),让所有业务错误继承它,便于统一识别和分类
- @ExceptionHandler 方法可接收 HttpServletRequest 或 WebRequest,轻松获取用户、traceId、请求路径等上下文
- 配合统一返回结构(如 Result
),让前端无需解析不同格式的错误响应
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











