java中应杜绝捕获throwable或泛型exception,只捕获具体异常类型;禁止在service、dao等中间层使用宽泛捕获,兜底逻辑须上移至@controlleradvice等受控入口,并通过静态检查工具和try-with-resources等手段从工程层面约束。

Java 中避免捕获 Throwable 或泛型 Exception 吞掉错误,核心是守住异常的语义边界:让该暴露的问题暴露,该处理的异常精准处理,该终止的错误不强行续命。
只捕获你明确知道如何响应的具体异常类型
业务代码里几乎不需要“兜底”,而是要“对症下药”:
- 文件操作就捕获
FileNotFoundException、SecurityException、IOException; - 数据库访问就捕获
SQLException,再细分SQLTimeoutException或SQLIntegrityConstraintViolationException; - JSON 解析就捕获
JsonProcessingException,而不是等它被包进Exception里消失; - 调用外部 HTTP 接口,优先捕获
IOException(连接失败)、TimeoutException(超时),而非笼统抓Exception。
绝对禁止在中间层写 catch (Exception) 或 catch (Throwable)
Service、DAO、Util、工具类这些地方,不是异常的终点,而是传播链的一环:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
-
catch (Throwable t)会吞掉OutOfMemoryError、StackOverflowError等 JVM 致命错误,程序可能卡死或行为错乱却无感知; -
catch (Exception e)会一并吃掉NullPointerException、IllegalArgumentException这类本该修复的逻辑缺陷,掩盖真实 Bug; - 真需要兜底,只允许出现在极少数受控入口:Spring 的
@ControllerAdvice、RPC 网关 Filter、全局线程处理器,且必须记录完整堆栈 + 快速失败(如返回降级结果)。
用工具和规范把错误写法挡在编码阶段
靠人盯不如靠机制卡:
- IntelliJ 中启用 inspection:“Catch Throwable” 和 “Catch Exception”,设为 error 级别,写完立刻标红;
- Maven/Gradle 集成 SpotBugs,开启规则
REC_CATCH_EXCEPTION和THROWABLE_INSTANCEOF,CI 构建失败即阻断; - 安装阿里巴巴 Java 开发规范插件,它会直接提示“禁止捕获 Throwable,应使用具体异常类型”;
- 在基础 SDK 中封装远程调用模板,把
Throwable处理收口到内部,对外只抛出定义清晰的业务异常(如RemoteServiceUnavailableException)。
用 try-with-resources 和前置校验减少“不得不 catch”的场景
很多泛捕获,其实是资源管理和输入控制没做好:
- 所有实现
AutoCloseable的资源(InputStream、Connection、HttpClient)一律用try-with-resources,自动释放,避免因finally关闭失败覆盖主异常; - 参数校验前置:用
Objects.requireNonNull()、StringUtils.isNotBlank()、正则预匹配,把NullPointerException、IllegalArgumentException拦在执行前; - 对易错操作封装安全方法:比如
safeParseJson()内部处理JsonProcessingException,对外只暴露语义明确的业务异常,不把技术细节甩给调用方。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










