ArrayIndexOutOfBoundsException是Java运行时下标越界异常,表现为访问负数或≥array.length的索引;常见于循环边界错误、未校验外部输入、多线程竞争等场景,应始终用arr.length校验且循环条件用

Java数组下标越界错误的典型表现
运行时抛出 ArrayIndexOutOfBoundsException,堆栈里明确指出访问了负数或 ≥ array.length 的索引。这不是编译错误,所以容易漏测——尤其在循环边界、嵌套计算索引、或从外部输入解析下标时。
常见触发场景包括:
for (int i = 0; i (多跑一次)-
arr[arr.length]或arr[-1] - 使用
Scanner.nextInt()读入索引但未校验范围 - 多线程共享数组且未同步读写位置
用 length 和边界检查代替“凭经验”硬编码
Java数组长度不可变,arr.length 是唯一可信依据。别假设“这个数组肯定有10个元素”。
实操建议:
立即学习“Java免费学习笔记(深入)”;
- 所有循环用
for (int i = 0; i ,严格用而非 - 访问前显式判断:
if (index >= 0 && index < arr.length) { return arr[index]; } else { throw new IllegalArgumentException("Index " + index + " out of bounds for array of length " + arr.length); } - 若逻辑依赖固定长度(如 RGB 颜色数组),优先用
enum或封装类,避免裸数组暴露下标操作
替代方案:用 ArrayList 或 Arrays.asList() 减少手动索引
当需要频繁增删、或不确定大小时,ArrayList 的 get(int) 方法仍会抛异常,但它配合 size() 更易统一管理;更重要的是,它支持 stream()、contains() 等不依赖下标的语义化操作。
例如:
- 查找元素:用
list.indexOf(obj)而非手写遍历+下标累加 - 安全取值:用
list.size() > index ? list.get(index) : null - 初始化固定内容:用
Arrays.asList("a", "b", "c"),返回的列表不可扩容,但避免了原始数组的裸下标风险
工具和习惯:静态检查与单元测试覆盖边界
IDE(如 IntelliJ)能高亮明显越界,但对动态计算索引无能为力。真正可靠的防线是测试:
- 每个接受索引参数的方法,至少覆盖三个用例:
index = 0index = arr.length - 1index = -1和index = arr.length - 使用
@Test(expected = ArrayIndexOutOfBoundsException.class)显式验证非法输入被拒绝 - 在 CI 中启用
errorprone或spotbugs,它们能捕获部分隐式越界模式(如arr[i + 1]未检查i )
越界问题本质不是语法缺陷,而是控制流与数据规模脱节。最常被忽略的点是:所有从用户、文件、网络来的下标值,都必须当作不可信输入处理,哪怕日志显示“它从来都是合法的”。










