java异常处理核心是分层判断、精准响应、可观测兜底;需区分error(不捕获,重预防)与exception,后者再分受检(强制处理)和非受检(优先修复);catch要具体,资源用try-with-resources清理;自定义异常应具业务语义并规范构造;严禁吞异常,须日志记录、结构化返回。

搞清异常类型:先分家,再动手
所有异常都从 Throwable 出生,但一出生就分两路:Error 和 Exception。
-
Error(错误) 是 JVM 自己扛不住的事,比如
OutOfMemoryError、StackOverflowError。别 catch,也 catch 不住——程序已失能。重点是预防:调优内存、限制递归深度、监控资源水位。 -
Exception(异常) 才是你该管的。再分两支:
-
受检异常(Checked):编译器盯得紧,像
IOException、SQLException。它说:“这事外部不可控,你必须明确表态——要么当场处理,要么声明甩给上层。” -
非受检异常(Unchecked):继承自
RuntimeException,如NullPointerException、IllegalArgumentException。编译器不管,但它是你代码的 bug 信号灯。优先修复逻辑,而不是无脑 catch。
-
受检异常(Checked):编译器盯得紧,像
用对处理方式:try-catch 不是万能胶
不是所有风险代码都值得套 try-catch。真正要保护的是有外部依赖、状态易变、资源需释放的操作。
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
- try 块里只放高危操作:比如文件读写、网络请求、数据库查询。别把校验逻辑、纯计算也塞进去。
-
catch 要具体,别写
catch (Exception e):捕获太宽泛会掩盖真实问题。优先按实际可能抛出的异常类型逐个 catch,比如FileNotFoundException和SecurityException处理方式完全不同。 -
finally 或 try-with-resources 必做资源清理:JDK 7+ 推荐用
try (Resource r = new Xxx()) { ... },自动关闭实现AutoCloseable的资源,比手写 finally 更安全、更简洁。
自定义异常:让错误会说话
抛出 new RuntimeException("用户没找到") 不如抛出 new UserNotFoundException("ID=123 不存在") —— 后者自带业务语义,日志一查就懂,前端也能直译成提示语。
- 继承
Exception→ 受检异常,强制调用方处理(适合必须响应的业务失败,如库存不足); - 继承
RuntimeException→ 非受检异常,用于可预期但无需强制捕获的业务异常(如参数校验失败、状态非法); - 每个自定义异常类提供三个构造方法:无参、带 message、带 message + cause;
- 类名以
Exception结尾,比如OrderAlreadyPaidException、InsufficientPermissionException。
生产级底线:别让异常消失在黑盒里
最危险的不是出错,而是出错后没人知道。
- 禁止
e.printStackTrace()或空 catch:它把异常吞进控制台,线上等于没日志; - catch 后至少记录日志,推荐 SLF4J + 具体异常级别(ERROR/WARN),带上上下文 ID、关键参数;
- 对外返回时,别把堆栈暴露给前端;内部用
e.getCause()或e.getSuppressed()挖深层原因; - Spring Boot 项目建议统一用
@ControllerAdvice + @ExceptionHandler做全局兜底,区分业务异常与系统异常,返回结构化错误响应。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










