Java 异常 ArrayIndexOutOfBoundsException

Java 操作数据时,偶尔会出现异常 ArrayIndexOutOfBoundsException。我们需要了解为什么会出现这个异常,以及如何避免出现这样的异常。

基础回顾

在Java中,数组是一种静态数据结构,我们在创建时就定义了它的大小。

我们使用索引访问数组的元素。数组中的索引从零开始,并且不能大于或等于数组的大小。

经验法则是 0 <= index < size

理解 ArrayIndexOutOfBoundsException

ArrayIndexOutOfBoundsException在我们访问一个数组或Collection时发生,该数组由具有无效索引的数组支持。这意味着索引小于零或大于或等于数组的大小。

此外,边界检查发生在运行时,ArrayIndexOutOfBoundsException是一个运行时异常。因此,我们在访问数组的边界元素时需要格外小心。

读取数组元素

访问数组时可能发生的最常见错误是忘记了上限和下限。

数组的下限始终为 0,而上限比其长度小 1。

访问超出这些范围的数组元素会抛出ArrayIndexOutOfBoundsException:

int[] numbers = new int[] {1, 2, 3, 4};
int lastNumber = numbers[4];

这里,数组的大小是 4,这意味着索引的范围是 0 到 3。

在这种情况下,访问第 4 个索引会导致ArrayIndexOutOfBoundsException:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 4

小于0的数也会出现相同的异常:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -2

读取列表

静态方法 Arrays.asList() 返回一个由指定数组支持的固定大小的列表。此外,它与数组类似,索引从零开始,范围为比其大小少一。

如果我们尝试访问超出此范围的Arrays.asList()返回的List的元素,会得到一个ArrayIndexOutOfBoundsException:

List<Integer> numbersList = Arrays.asList(1, 2, 3, 4);
int lastNumber = numbersList.get(4);

错误边界处理

有时,在 for 循环中迭代数组时,我们可能会输入错误的终止表达式。

我们可能最终迭代直到它的长度,而不是在比数组长度小一的位置终止索引:

int[] numbers = new int[] {1, 2, 3, 4};
int sum = 0;
for (int i = 0; i <= numbers.length; i++) {
    sum += numbers[i];
}

for 的退出条件是,循环变量 i 等于或小于数组长度,在遍历的最后一次迭代中, i 为4,超出了数组长度,会导致 ArrayIndexOutOfBoundsException。

如何避免ArrayIndexOutOfBoundsException

既然已经知道了异常是如何产生的,我们需要从下面几个方面去考虑,如何避免在程序中出现 ArrayIndexOutOfBoundsException。

注意索引下标区间

我们必须始终记住,Java 的数组索引从 0 开始。因此,第一个元素始终位于索引 0 处,而最后一个元素位于比数组长度小 1 处的索引处。

使用 forEach

传统的 for 循环存在最后一个数据的边界问题,错误地使用运算符 <、<=、> 或 >= 是发生此异常的常见原因。

因此,我们在遍历数组时,才用增强 for 循环,它不设计索引下标:

for (int number : numbers) {
    sum += number;
}

JVM 会正确地处理数组下标,避免出现 ArrayIndexOutOfBoundsException。

标签: