RuntimeException是Java非受检异常基类,编译器不强制处理,反映程序逻辑缺陷,核心原则是预防优于兜底;其7个常见子类包括NullPointerException(空引用操作)、ArrayIndexOutOfBoundsException(数组越界)、StringIndexOutOfBoundsException(字符串索引越界)等,均需通过前置校验、边界控制和主动防御来规避。

RuntimeException 是 Java 中非受检异常的基类,编译器不强制要求捕获或声明,它反映的是程序逻辑缺陷,核心思路是“预防优于兜底”。下面梳理最常遇到的 7 个子类,聚焦典型触发场景和务实应对方式。
NullPointerException:空引用误操作
这是开发中最高频的运行时异常。本质是把 null 当作了有效对象来使用——调用方法、访问字段、执行数组/集合操作,甚至自动拆箱包装类型都会触发。
- 常见写法:
String s = null; s.length();、Integer i = null; int n = i;、list.add(null); list.get(0).toString(); - 推荐做法:方法入参用
Objects.requireNonNull()主动校验;返回值用Optional封装;集合操作前判空或用CollectionUtils.isNotEmpty()(Apache Commons)
ArrayIndexOutOfBoundsException 与 StringIndexOutOfBoundsException
两者都属索引越界范畴,前者针对数组,后者专用于字符串,底层都是对无效下标(负数或 ≥ 容器长度)的访问。
- 典型例子:
int[] a = {1,2}; a[5];、"ab".charAt(10); - 关键防范点:循环中严格使用
array.length或str.length()控制边界;从外部接收索引时做范围校验(如if (i >= 0 && i )
ClassCastException:非法类型强转
发生在运行时类型不兼容的强制转换中,尤其在泛型擦除后绕过编译检查的操作里高发。
- 典型代码:
Object obj = "hello"; Integer i = (Integer) obj;、List<string> l1 = new ArrayList(); List<integer> l2 = (List<integer>) l1;</integer></integer></string> - 安全写法:转换前用
instanceof判断;优先用泛型明确类型;避免原始类型集合与泛型混用
ArithmeticException:算术运算违规
最常见的是整数除零,浮点数除零不会抛此异常(结果为 Infinity),所以需特别注意 int/long 类型的除法。
- 示例:
int x = 10 / 0;、BigDecimal.divide()未指定舍入模式导致无限小数 - 建议:涉及用户输入或配置的除法,先判断除数是否为零;金融计算统一用
BigDecimal并显式设置RoundingMode
IllegalArgumentException 与 NumberFormatException
前者是参数合法性总类异常,后者是其常用子类,专指字符串无法解析为数字。
- 常见触发:
Thread.sleep(-1)、Integer.parseInt("abc")、LocalDate.parse("2026-13-01") - 处理原则:对外部输入(表单、配置、API 参数)做前置校验;用正则或工具类(如 Apache Commons
StringUtils.isNumeric())预筛;抛出异常时附带清晰提示(如 “年龄必须为正整数”)
IllegalStateException:状态不匹配
对象当前所处状态不支持该操作,多见于状态机、迭代器、流式 API 和框架回调中。
- 典型场景:
Iterator.next()前未调用hasNext();Stream.collect()后再次调用forEach();Spring Bean 在未初始化完成时被注入使用 - 规避要点:遵循 API 文档中的调用顺序约定;状态变更后及时更新内部标志位;单元测试覆盖边界状态流转
UnsupportedOperationException:操作未实现
多出现在集合框架中——某些集合(如 Arrays.asList() 返回的列表、Collections.unmodifiableList())重写了修改方法并直接抛出该异常。
- 例子:
List<string> list = Arrays.asList("a"); list.add("b");</string> - 识别方式:查看文档或源码确认集合是否支持增删改;需要可变集合时,显式构造
new ArrayList(original);不要假设所有List都可写

















