java受检异常是编译期强制处理的exception子类(非runtimeexception),用于显式建模可预期、可恢复的外部风险(如i/o、数据库、网络失败),体现契约式编程思想;非受检异常继承自runtimeexception或error,代表程序逻辑缺陷或系统级故障,无需编译期强制处理。

面试中问到Java异常分类,不是让你背定义,而是看你能不能讲清楚设计意图、使用场景和实际影响。关键在理解“为什么要有受检异常”以及“什么时候该用哪种异常”。
受检异常(Checked Exception):编译器强制你面对的问题
受检异常继承自Exception(但不包括RuntimeException),比如IOException、SQLException。Java要求你必须显式处理——要么try-catch,要么在方法签名里throws声明。
- 设计初衷是针对**可预期、可恢复的外部问题**,比如文件不存在、网络超时、数据库连接失败
- 不能靠“忽略”来过关:不处理,代码直接编译失败
- 注意:子类继承受检异常,仍是受检异常;但若继承自RuntimeException,哪怕父类是受检异常,也变成非受检
非受检异常(Unchecked Exception):运行时才暴露的逻辑问题
包括RuntimeException及其所有子类(如NullPointerException、ArrayIndexOutOfBoundsException),还有Error(如OutOfMemoryError)。它们在编译期不强制处理。
- 代表**程序逻辑缺陷或不可控的系统级故障**,比如空指针、数组越界、除零、内存耗尽
- 通常不该捕获Error,也不建议盲目catch RuntimeException——修复bug比兜底更重要
- 自定义异常时,若想让它非受检,就继承RuntimeException;想让它受检,就继承Exception
怎么选?看责任归属和恢复可能性
判断一个异常该设计成受检还是非受检,核心是问两个问题:
- 调用方有没有能力/责任去响应它?比如读文件失败,调用方可以重试、换路径、提示用户——适合受检
- 这个错误是不是本该在开发阶段就被发现?比如传入null导致NPE,属于编码疏漏,应通过测试暴露,而非靠异常处理掩盖——适合非受检
- 现代实践倾向更谨慎地使用受检异常:过度使用会污染API、增加模板代码;Spring等主流框架大量将底层受检异常转为非受检(如DataAccessException),就是基于这一权衡
面试加分点:说清常见误区
很多候选人能分清类型,但一聊细节就露馅:
- 误以为Exception全是受检异常——忘了RuntimeException也是它的子类
- 认为“捕获Exception就能抓住所有异常”——其实Error不会被它捕获,除非写catch (Throwable t)(一般不推荐)
- 把业务校验失败(如“余额不足”)抛受检异常——这类明确的业务规则更适合自定义非受检异常,避免调用方被迫处理“本不该发生却常发生”的情况
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











