java异常处理核心是让错误行为可预期、影响可控制、问题可追溯;应分层捕获具体异常,禁用catch(exception e),不捕获error,对受检异常需恢复处理,运行时异常应包装为带错误码的业务异常,资源管理强制使用try-with-resources,异常需驱动容错策略并统一出口日志。

异常处理不是让程序“不报错”,而是让系统在出错时行为可预期、影响可控制、问题可追溯。真正提升Java系统稳定性,关键在于把异常当作业务信号来设计,而不是被动兜底。
分层捕获具体异常,避免一锅端
用 catch (Exception e) 或更糟的 catch (Throwable t) 会掩盖真实问题。JVM级错误(如 OutOfMemoryError)不该被业务代码捕获,而业务可恢复场景(如网络超时)和逻辑缺陷(如空指针)必须区别对待:
- 对 IOException、SQLException 等受检异常,单独捕获并执行重试、降级或提示用户重试
- 对 NullPointerException、IllegalArgumentException 等运行时异常,不静默吞掉,而是记录完整上下文后包装为带错误码的业务异常(如 InvalidOrderException)再抛出
- 绝不捕获 Error 及其子类——它们意味着JVM已无法维持基本运行
资源管理必须自动化
文件流、数据库连接、HTTP客户端等资源未释放,轻则内存泄漏,重则服务雪崩。Java 7+ 的 try-with-resources 是强制标准:
- 所有实现 AutoCloseable 的资源(如 Connection、InputStream、HttpClient)必须声明在 try 括号内
- 即使发生异常,JVM 保证 close() 被调用;无需手动写 finally 块关流
- 若需额外清理动作(如解锁、清缓存),才在 finally 中补充,且其中也应加 try-catch 防止新异常覆盖原异常
用异常驱动业务容错策略
异常是断路器、重试、降级的天然触发器。不能只靠 try-catch,而要结合语义化分类:
- 将 ConnectException、SocketTimeoutException 视为“可重试基础设施异常”,纳入失败计数,达到阈值后自动熔断
- 将 BusinessRejectedException(自定义)视为“明确业务拒绝”,不计入熔断统计,直接走降级逻辑
- 在 Service 层关键远程调用处使用 @CircuitBreaker 注解,并配 @Fallback 方法返回默认值或缓存结果,而非抛新异常
统一出口 + 有意义的日志
异常最终要落到用户或监控系统,不能散落在各处处理:
- 用 Spring 的 @ControllerAdvice 或全局过滤器集中捕获未处理异常,统一返回结构化 JSON(含错误码、简明提示、traceId)
- 日志必须用 SLF4J 等框架记录,且每条异常日志包含:关键业务参数(如 orderId)、操作人、时间戳、原始异常堆栈
- 禁止 e.printStackTrace() —— 它只适合本地调试,生产环境等于丢弃关键线索
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











