java自定义异常多catch块的核心是让业务错误可识别、分类和响应,需按具体性从高到低排列,继承runtimeexception或exception区分受检与否,提供含上下文的构造方法,避免捕获exception/throwable,同质异常可用多重catch合并处理,捕获后应转换提示、记录日志、包装再抛出。

Java中捕获自定义异常的多catch块,核心在于让业务逻辑错误可识别、可分类、可响应。不是简单替换Exception,而是通过异常类型直接表达“发生了什么”,比如余额不足和优惠码无效应走不同处理路径。
自定义异常类要继承明确的父类
根据是否需强制处理,选择继承RuntimeException(非受检)或Exception(受检):
- 业务校验类错误(如参数非法、状态不合法)→ 继承RuntimeException,调用方无需强制try或throws
- 外部依赖失败类错误(如支付网关超时、库存服务不可达)→ 继承Exception,强制上层决策是重试还是降级
- 所有自定义异常都应提供含业务上下文的构造方法,例如:new InsufficientBalanceException("订单123456,SKU-789缺货2件")
多catch块按具体性从高到低排列
Java编译器要求子类异常必须写在父类之前,否则后续catch永远无法触发。例如:
- 先catch InvalidPromoCodeException(最具体)
- 再catch InsufficientBalanceException(同级具体)
- 接着catch PaymentRejectedException(另一业务域)
- 最后catch BusinessException(自定义基类,兜底)
- 不建议catch Exception或Throwable——会吞掉本该暴露的系统级问题
同质异常可用单catch合并处理
当多个异常代表同一类业务后果(如“下游不可用”),可用Java 7+的多重捕获语法简化代码:
- 写法:catch (TimeoutException | ConnectException | IOException e)
- 前提:这些异常之间不能有继承关系,否则编译报错
- 适用场景:微服务调用中,网络层各种失败统一触发熔断或返回“服务暂不可用”
- 注意:仍需在catch内判断e.getClass()做细粒度日志,便于监控区分失败原因
异常捕获后别只打印堆栈
捕获自定义异常不是终点,而是业务响应的起点:
- 对用户:转换为前端友好的提示,如“优惠码已过期”而非“InvalidPromoCodeException”
- 对系统:记录结构化日志,包含订单ID、用户ID、异常类型、时间戳,方便聚合分析
- 对流程:主动包装再抛出,补充当前上下文,例如:throw new OrderSubmitFailedException("创建订单失败", orderId, e)
- 资源清理优先用try-with-resources,避免在catch里手动close引发二次异常
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











