Java ArrayIndexOutOfBoundsException – Java ArrayIndexOutOfBoundsException

最后修改: 2022年 2月 8日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

In this tutorial, we’ll discuss ArrayIndexOutOfBoundsException in Java. We’ll understand why it occurs and how to avoid it.

在本教程中,我们将讨论Java中的ArrayIndexOutOfBoundsException。我们将了解它发生的原因以及如何避免它。

2. When Does ArrayIndexOutOfBoundsException Occur?

2.什么时候发生ArrayIndexOutOfBoundsException

As we know, in Java, an array is a static data structure, and we define its size at the time of creation.

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

We access the elements of an array using indices. Indexing in an array starts from zero and must never be greater than or equal to the size of the array.

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

In short, the rule of thumb is 0 <= index < (size of array).

简而言之,经验法则是0 <= index <(数组的大小)。

ArrayIndexOutOfBoundsException occurs when we access an array, or a Collection, that is backed by an array with an invalid index. This means that the index is either less than zero or greater than or equal to the size of the array.

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

Additionally, bound checking happens at runtime. So, ArrayIndexOutOfBoundsException is a runtime exception. Therefore, we need to be extra careful when accessing the boundary elements of an array.

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

Let’s understand some of the common operations that lead to ArrayIndexOutOfBoundsException.

让我们了解一些导致ArrayIndexOutOfBoundsException的常见操作。

2.1. Accessing an Array

2.1.访问一个数组

The most common mistake that may happen while accessing an array is forgetting about the upper and lower bounds.

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

The lower bound of an array is always 0, while the upper bound is one less than its length.

一个数组的下限总是0,而上限是比其长度少一个。

Accessing the array elements out of these bounds would throw an ArrayIndexOutOfBoundsException:

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

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

Here, the size of the array is 5, which means the index will range from 0 to 4.

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

In this case, accessing the 5th index results in an ArrayIndexOutOfBoundsException:

在这种情况下,访问第5个索引就会出现ArrayIndexOutOfBoundsException

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 5 out of bounds for length 5
    at ...

Similarly, we get ArrayIndexOutOfBoundsException if we pass a value less than zero as an index to numbers.

同样,如果我们向numbers.传递一个小于0的值作为索引,我们会得到ArrayIndexOutOfBoundsException

2.2. Accessing a List Returned by Arrays.asList()

2.2.访问由Arrays.asList()返回的列表

The static method Arrays.asList() returns a fixed-sized list that is backed by the specified array. Moreover, it acts as a bridge between array-based and collection-based APIs.

静态方法Arrays.asList()返回一个固定大小的列表,该列表以指定的数组为支撑。此外,它还充当了基于数组和基于集合的API之间的桥梁。

This returned List has methods to access its elements based on indices. Also, similar to an array, the indexing starts from zero and ranges to one less than its size.

这个返回的List有基于索引的方法来访问其元素。另外,与数组类似,索引从零开始,范围是比它的大小少一个。

If we try to access the elements of the List returned by Arrays.asList() beyond this range, we would get an ArrayIndexOutOfBoundsException:

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

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

Here again, we are trying to get the last element of the List. The position of the last element is 5, but its index is 4 (size – 1). Hence, we get ArrayIndexOutOfBoundsException as below:

在这里,我们再次试图获得List中的最后一个元素。最后一个元素的位置是5,但是它的索引是4(大小-1)。因此,我们得到ArrayIndexOutOfBoundsException,如下。

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 5 out of bounds for length 5
    at java.base/java.util.Arrays$ArrayList.get(Arrays.java:4351)
    at  ...

Similarly, if we pass a negative index, say -1, we will get a similar result.

同样,如果我们传递一个负的索引,例如-1,我们将得到一个类似的结果。

2.3. Iterating in Loops

2.3.循环中的迭代

Sometimes, while iterating over an array in a for loop, we might put a wrong termination expression.

有时,在for循环中对数组进行迭代时,我们可能会放置一个错误的终止表达式。

Instead of terminating the index at one less than the length of the array, we might end up iterating until its length:

而不是在比数组长度少一个的地方终止索引,我们可能最终迭代到它的长度。

int sum = 0;
for (int i = 0; i <= numbers.length; i++) {
    sum += numbers[i];
}

In the above termination expression, the loop variable is being compared as less than or equal to the length of our existing array numbers. So, in the last iteration, the value of will become 5.

在上述终止表达式中,循环变量i被比较为小于或等于我们现有数组numbers的长度。i 的值将变成5。

Since index 5 is beyond the range of numbers, it will again lead to ArrayIndexOutOfBoundsException:

由于索引5超出了数字的范围,它将再次导致ArrayIndexOutOfBoundsException

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 5 out of bounds for length 5
    at com.baeldung.concatenate.IndexOutOfBoundExceptionExamples.main(IndexOutOfBoundExceptionExamples.java:22)

3. How to Avoid ArrayIndexOutOfBoundsException?

3.如何避免ArrayIndexOutOfBoundsException

Let’s now understand some ways to avoid ArrayIndexOutOfBoundsException.

现在让我们了解一些方法来避免ArrayIndexOutOfBoundsException

3.1. Remembering the Start Index

3.1.记住起始索引

We must always remember that the array index starts at 0 in Java. So, the first element is always at index 0, while the last element is at index one less than the length of the array.

我们必须永远记住,在Java中,数组的索引从0开始。所以,第一个元素总是在索引0处,而最后一个元素的索引比数组的长度小1。

Remembering this rule will help us avoid ArrayIndexOutOfBoundsException most of the time.

记住这个规则将帮助我们在大多数时候避免ArrayIndexOutOfBoundsException

3.2. Correctly Using the Operators in Loops

3.2.正确地使用循环中的操作符

Incorrectly initializing the loop variable to index 1 may result in ArrayIndexOutOfBoundsException.

不正确地将循环变量初始化为索引1可能导致ArrayIndexOutOfBoundsException

Similarly, the incorrect use of operators <, <=, > or >= in termination expressions of loops is a common reason for the occurrence of this exception.

类似地,在循环的终止表达式中不正确地使用运算符<、<=、>或>=是发生这种异常的一个常见原因。

We should correctly determine the use of these operators in loops.

我们应该正确判断这些运算符在循环中的使用。

3.3. Using Enhanced for Loop

3.3.使用增强的for循环

If our application is running on Java 1.5 or a higher version, we should use an enhanced for loop statement that has been specifically developed to iterate over collections and arrays. Also, it makes our loops more succinct and easy to read.

如果我们的应用程序运行在Java 1.5或更高的版本上,我们应该使用增强的for loop语句,它是专门为迭代集合和数组而开发的。而且,它使我们的循环更加简洁,易于阅读。

Additionally, using the enhanced for loop helps us completely avoid the ArrayIndexOutOfBoundsException as it does not involve an index variable:

此外,使用增强的for循环可以帮助我们完全避免ArrayIndexOutOfBoundsException,因为它不涉及索引变量

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

Here, we do not have to worry about indexing. The enhanced for loop picks up an element and assigns it to a loop variable, number, with each iteration. Thus, it completely avoids ArrayIndexOutOfBoundsException.

在这里,我们不必担心索引的问题。增强的for循环会拾取一个元素,并在每次迭代时将其分配给一个循环变量number。因此,它完全避免了ArrayIndexOutOfBoundsException

4. IndexOutOfBoundsException vs. ArrayIndexOutOfBoundsException

4.IndexOutOfBoundsExceptionArrayIndexOutOfBoundsException

IndexOutOfBoundsException occurs when we try to access an index of some type (String, array, List, etc.) beyond its range. It’s a superclass of ArrayIndexOutOfBoundsException and StringIndexOutOfBoundsException.

IndexOutOfBoundsException发生在我们试图访问某种类型(String、数组、List等)的索引超出其范围时。它是ArrayIndexOutOfBoundsExceptionStringIndexOutOfBoundsException的一个超类。

Similar to ArrayIndexOutOfBoundsException, StringIndexOutOfBoundsException is thrown when we try to access a character of a String with an index beyond its length.

ArrayIndexOutOfBoundsException类似,StringIndexOutOfBoundsException在我们试图访问String的某个字符时,索引超出其长度,就会被抛出。

5. Conclusion

5.总结

In this article, we explored ArrayIndexOutOfBoundsException, some examples for how it occurs, and some common techniques to avoid it.

在这篇文章中,我们探讨了ArrayIndexOutOfBoundsException,一些关于它如何发生的例子,以及一些避免它的常见技术。

As always, the source code for all of these examples is available over on GitHub.

一如既往,所有这些例子的源代码都可以在GitHub上找到