java多catch需按继承关系从子类到父类排列,否则子类异常无法捕获;可使用multi-catch合并无继承关系的异常;应定义语义化业务异常并包装上下文;资源清理优先用try-with-resources,补偿操作应封装复用。

Java里多catch不是为了凑数,而是让每种异常落到它该去的地方——具体问题具体响应,不模糊、不遗漏。
按继承关系从细到粗排列
catch块顺序直接影响能否捕获到真实异常。子类异常必须写在父类前面,否则编译器会报“不可达代码”错误。
- 正确写法:先`FileNotFoundException`,再`IOException`,最后`Exception`
- 错误写法:把`Exception`放在最前,后面所有具体异常都失效
- 常见误区:以为只要写了多个catch就能覆盖全部,其实顺序错等于没写
同质异常用multi-catch合并处理
当几种异常需要执行完全一致的操作(比如统一记录日志、返回相同错误码),Java 7起支持用竖线(|)在一个catch中声明多个互不继承的异常类型。
- 写法示例:
catch (SQLException | IOException e) - 限制条件:这些异常不能有父子关系,否则编译失败
- e变量是final的,类型为它们最近的公共父类(通常是Exception),不能直接调用子类特有方法
业务异常优先定义语义化类型
别总依赖catch (Exception e)兜底。它会抹掉关键上下文,让排查变困难。
- 推荐做法:定义如
InsufficientStockException、PromotionExpiredException等带业务含义的异常 - 好处是上层能根据类型做差异化动作——重试、跳过、提示用户,而不是一律告警
- 捕获时可包装上下文再抛出:
throw new OrderValidationException("库存不足", orderId, skuId)
资源清理必须与异常处理协同
多catch解决“怎么响应”,但资源是否释放、状态是否回滚,得另外设计。
- 优先使用
try-with-resources,自动关闭Closeable资源,比手动finally更可靠 - 如果catch中需补偿操作(如事务回滚),应封装成私有方法,在各相关catch块里调用,避免重复
- 注意:若try中抛异常且资源关闭也失败,后者会作为suppressed异常附加到主异常上,排查时记得调用
e.getSuppressed()
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











