编译器会拦截checked异常(如IOException),不处理则编译失败;unchecked异常(如NullPointerException、Error)编译器不检查。前者是Exception非RuntimeException子类,后者是RuntimeException或Error子类。

编译器会不会拦你?这是最直接的区分标准
Java里,checked异常是编译器强制你处理的:如果方法里调用了可能抛出IOException或SQLException的代码,又没用try-catch包住,也没在方法签名加throws IOException,javac直接报错,不让你编译通过。
而unchecked异常(即RuntimeException及其子类,比如NullPointerException、ArrayIndexOutOfBoundsException)完全不受编译器约束——你爱捕获就捕获,不写也行,编译照过。
它们分别继承自哪个父类?别靠记忆,看源码更准
所有异常都源自Throwable,但分叉点很明确:
• checked异常是Exception的子类,但**排除**RuntimeException及其全部后代;
• unchecked异常就是RuntimeException和Error(如OutOfMemoryError)这两支。
注意:Error虽属unchecked,但它代表JVM级灾难,一般不该也不必捕获——这不是程序该处理的问题。
什么时候该用try-catch,什么时候该提前防御?
对checked异常,别总想着“一把抓”:
• FileNotFoundException不是bug,是外部状态(文件可能被删),适合用try-catch兜底并提示用户重试;
• 但NullPointerException是典型的unchecked异常,说明你没校验入参或对象初始化失败——这时候补个if (obj != null)比写catch (NullPointerException e)更合理、更高效。
常见误区:
• 在工具方法里盲目throws Exception,把checked异常甩给调用方,反而让上层逻辑更难决策;
• 对ArithmeticException(如除零)用try-catch掩盖,而不检查分母是否为0。
为什么有些框架偏爱unchecked异常?
Spring、Hibernate等主流框架大量使用RuntimeException子类(如DataAccessException)替代传统SQLException,原因很实际:
• 调用方几乎无法从SQL异常中恢复,强制声明throws SQLException只会污染接口;
• 统一转成unchecked后,开发者可选择在事务边界统一拦截(如@ExceptionHandler),而不是每层都写try-catch;
• 避免了“为了编译通过而throw”的伪异常处理——比如空catch块或只打日志却不响应。
立即学习“Java免费学习笔记(深入)”;
真正容易被忽略的点是:checked异常不是“更严重”,而是“更可预期”;unchecked异常不是“可以不管”,而是“该在编码阶段就掐灭”。写throws IOException不等于健壮,漏掉一个null检查却可能在线上崩得毫无征兆。










