应只捕获具体异常类型而非Exception或Throwable,确保异常语义清晰、处理动作明确、错误不被静默丢弃;中间层禁止泛捕,兜底逻辑统一收口至Web层或网关层,并通过工具强制约束宽泛捕获。

直接捕获 Exception 或 Throwable 会把空指针、内存溢出、数组越界等本该暴露的问题一并吃掉,导致线上故障难定位、逻辑跳过无感知。关键不是“少写 catch”,而是让异常类型清晰、处理动作明确、错误不被静默丢弃。
只捕获你能真正处理的具体异常类型
每种异常代表不同语义,捕获前先问自己:这个异常发生时,我是否知道确切的恢复方式?
- 调用外部 HTTP 接口失败 → 单独
catch (IOException | TimeoutException e),做重试或降级 - 读取配置文件不存在 →
catch (FileNotFoundException e),加载默认值并记录 warn 日志 - 数据库操作失败 →
catch (SQLException e),根据 SQLState 判断是连接中断还是唯一键冲突,分别应对 - 解析 JSON 失败 → 不 catch
Exception,而是封装safeParseJson()方法内部处理JsonProcessingException,对外抛出语义明确的InvalidConfigException
把兜底逻辑移到统一入口,中间层禁止泛捕
业务方法、工具类、DAO 层不该承担“防崩”责任——它们只负责抛出或转换异常。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- Web 层用
@ControllerAdvice+ 多个@ExceptionHandler,分别处理ValidationException、HttpClientErrorException、RuntimeException - RPC 客户端或网关层可有限 catch
Throwable,但必须完整记录堆栈、快速失败(如返回兜底数据),且绝不继续执行后续业务逻辑 - Service/Util/Repository 中出现
catch (Exception e)视为代码缺陷,CI 流水线应直接拒绝构建
用防御式编程和资源自动管理减少“不得不 catch”的场景
很多泛捕是因为前期没做好校验或资源控制,结果只能靠 catch 来兜底。
立即学习“Java免费学习笔记(深入)”;
- 空值、非法参数提前拦截:
Objects.requireNonNull(id, "id must not be null")、StringUtils.isNotBlank(name) - 所有实现
AutoCloseable的资源(文件流、连接、HTTP client)一律用try-with-resources,无需finally关闭,也避免因关闭失败引发二次异常干扰主逻辑 - 对第三方 SDK 调用,优先查阅其文档,确认是否支持更细粒度的异常声明(比如把
throws Throwable替换为throws ApiTimeoutException, ApiResponseException)
借助工具让宽泛捕获在编码阶段就无法通过
靠人记住规则容易疏漏,要让系统强制约束。
- IntelliJ 中启用 Inspections:搜索 “Too broad catch”,设为 Error 级别;同时勾选 “Catch Throwable” 和 “Catch Exception” 警告
- Maven/Gradle 集成 SpotBugs,配置规则
REC_CATCH_EXCEPTION和THROWABLE_INSTANCEOF,CI 检测到即失败 - 安装阿里巴巴 Java 开发规约插件,它会实时标出所有
catch (Exception e)并提示“应捕获具体异常类型”

















