unchecked异常指RuntimeException及其子类和Error及其子类,但实际关注重点是RuntimeException体系;其特点是编译不强制捕获、运行时暴露、根源为代码逻辑缺陷,应通过校验和测试预防而非try-catch兜底。

Java里 unchecked 异常就是 RuntimeException 及其所有子类,加上 Error 类及其子类——但实际开发中真正需要你关注的,几乎全是 RuntimeException 体系下的那些。
哪些异常属于 unchecked(编译器不强制捕获)
它们的特点是:编译时不会报错,运行时才暴露,根源基本是代码逻辑缺陷,该修代码而不是硬加 try-catch。
-
NullPointerException:调用null对象的方法或字段,比如str.length()中str == null -
ArithmeticException:典型如int c = a / b中b == 0 -
ArrayIndexOutOfBoundsException:数组访问越界,如arr[10]而arr.length == 5 -
ClassCastException:非法强转,如(Integer)"hello" -
IllegalArgumentException:方法参数明显非法,如Objects.requireNonNull(null)或LocalDateTime.parse("invalid") -
IllegalStateException:对象状态不满足调用前提,如Iterator.next()在无元素时调用 -
ConcurrentModificationException:遍历集合时被其他线程/代码修改(如增强 for 循环里list.remove())
为什么它们不强制处理?关键在“责任归属”
unchecked 异常本质是程序写错了,不是外部环境问题。编译器不拦你,是因为它认为:这类错误本不该发生,你应该靠逻辑校验、单元测试、静态分析(如 SpotBugs)提前发现,而不是靠运行时兜底。
- 加
try-catch捕获NullPointerException是治标不治本,掩盖了空值来源没校验的问题 - 用
throws RuntimeException声明方法可能抛出 unchecked 异常毫无意义——编译器根本不认 -
Error(如OutOfMemoryError)更不能 catch,JVM 都快崩了,你的业务代码没能力恢复
实战中怎么应对 unchecked 异常
不是不管,而是换种方式“防”和“控”:
立即学习“Java免费学习笔记(深入)”;
- 用
Objects.requireNonNull(obj, "msg")主动快速失败,比静默null后崩溃更易定位 - 集合操作优先用
Optional封装可能为null的返回值:Optional
userOpt = Optional.ofNullable(userDao.findById(id)); User user = userOpt.orElseThrow(() -> new BusinessException("用户不存在")); - 边界检查前移:参数校验放方法入口(Spring Boot 可用
@Valid),不用等执行到array[i]才爆IndexOutOfBoundsException - 日志中记录异常堆栈时,别只打
e.getMessage()——e.printStackTrace()或用 SLF4J 的logger.error("xxx", e)才能保留完整上下文
最容易被忽略的一点:很多团队把 IllegalArgumentException 或 IllegalStateException 当成“提示性异常”随意 throw,却没统一错误码和语义,导致前端无法区分是用户输错还是系统故障。这类异常应该有明确契约——什么输入触发、对应哪类业务场景、是否可重试,否则就只是披着异常外衣的隐藏 bug。










