ResourceNotFoundException 应继承 Exception 而非 RuntimeException,以强制显式处理;需提供含 resourceType 和 resourceId 的语义化构造方法,并支持异常链;配合@ControllerAdvice 统一返回 404 响应,避免与 NullPointerException 混用。

ResourceNotFoundException 是典型的业务异常,用于明确表达“请求的资源不存在”这一语义。它不该继承 RuntimeException(避免掩盖逻辑错误),而应继承 Exception,强制调用方显式处理,体现“资源缺失是可预期、需响应”的设计意图。
继承 Exception,不继承 RuntimeException
资源找不到不是程序 bug,而是正常业务分支(如用户访问一个已删除的文章 ID)。若定义为运行时异常,容易被忽略,导致 404 返回不一致或日志缺失。
- 继承
Exception:调用方必须 try-catch 或 throws,利于统一错误拦截和 HTTP 状态码映射(如 Spring MVC 中自动转为 404) - 避免空参构造:至少提供 message 和 cause 重载,方便链路追踪
- 推荐添加资源类型与标识字段,便于日志和监控识别
提供语义化构造方法
让使用者能清晰表达“什么资源、哪个 ID 没找到”,而不是拼接字符串。
-
ResourceNotFoundException(String resourceType, Object resourceId)→ 自动生成类似 "User not found with id: 123" -
ResourceNotFoundException(String message, Throwable cause)→ 支持异常链(如底层 DAO 抛出 SQLException 时包装) - 可选:增加
getResourceType()和getResourceId()方法,供全局异常处理器提取结构化信息
配合框架做统一响应处理
在 Spring Boot 中,通过 @ControllerAdvice 捕获该异常并返回标准 JSON + HTTP 404:
立即学习“Java免费学习笔记(深入)”;
- 响应体包含 code(如 "NOT_FOUND")、message、timestamp、甚至 resourceType/resourceId 字段
- 避免在 service 层吞掉异常或返回 null,保持分层职责清晰
- 前端可根据 code 做差异化提示(如跳转 404 页面 or 弹窗提示“该商品已下架”)
避免和 NullPointerException 混用
不要因为对象为 null 就直接 throw ResourceNotFoundException——null 可能是未初始化、缓存穿透或参数校验失败,需先判断原因。
- DAO 层查不到数据 → 明确 throw ResourceNotFoundException
- 入参为 null → 应抛 IllegalArgumentException(参数非法)
- 上游服务返回 null 且无错误码 → 需先封装/转换,再决定是否转为资源未找到


















