Перейти к основному содержимому

Java ArrayIndexOutOfBoundsException

· 5 мин. чтения

1. Обзор

В этом руководстве мы обсудим исключение ArrayIndexOutOfBoundsException в Java. Разберемся, почему это происходит и как этого избежать.

2. Когда возникает исключение ArrayIndexOutOfBoundsException ?

Как известно, в Java массив — это статическая структура данных, и мы определяем его размер в момент создания.

Мы обращаемся к элементам массива, используя индексы. Индексация в массиве начинается с нуля и никогда не должна быть больше или равна размеру массива.

Короче говоря, эмпирическое правило таково: 0 <= index < (размер массива).

ArrayIndexOutOfBoundsException возникает, когда мы обращаемся к массиву или коллекции , которая поддерживается массивом с недопустимым индексом. Это означает, что индекс либо меньше нуля, либо больше или равен размеру массива.

Кроме того, проверка привязки происходит во время выполнения. Таким образом, ArrayIndexOutOfBoundsException является исключением времени выполнения. Поэтому нам нужно быть особенно осторожными при доступе к граничным элементам массива.

Давайте разберемся с некоторыми распространенными операциями, которые приводят к ArrayIndexOutOfBoundsException .

2.1. Доступ к массиву

Самая распространенная ошибка, которая может произойти при доступе к массиву, — забыть о верхней и нижней границах.

Нижняя граница массива всегда равна 0, а верхняя граница на единицу меньше его длины.

Доступ к элементам массива за пределами этих границ вызовет ArrayIndexOutOfBoundsException :

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

Здесь размер массива равен 5, что означает, что индекс будет варьироваться от 0 до 4.

В этом случае доступ к 5-му индексу приводит к ArrayIndexOutOfBoundsException :

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

Точно так же мы получаем ArrayIndexOutOfBoundsException , если передаем значение меньше нуля в качестве индекса к числам.

2.2. Доступ к списку , возвращаемому Arrays.asList()

Статический метод Arrays.asList() возвращает список фиксированного размера, поддерживаемый указанным массивом. Более того, он действует как мост между API-интерфейсами на основе массивов и коллекций.

Этот возвращенный список имеет методы для доступа к своим элементам на основе индексов. Кроме того, как и в случае с массивом, индексация начинается с нуля и колеблется на единицу меньше его размера.

Если мы попытаемся получить доступ к элементам списка , возвращаемого Arrays.asList() за пределами этого диапазона, мы получим исключение ArrayIndexOutOfBoundsException :

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

Здесь мы снова пытаемся получить последний элемент списка . Позиция последнего элемента — 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 ...

Точно так же, если мы передадим отрицательный индекс, скажем -1, мы получим аналогичный результат.

2.3. Итерация в циклах

Иногда при переборе массива в цикле for мы можем ввести неправильное выражение завершения.

Вместо того, чтобы заканчивать индекс на единицу меньше, чем длина массива, мы могли бы закончить итерацию до его длины:

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

В приведенном выше выражении завершения переменная цикла i сравнивается как меньшая или равная длине наших существующих номеров массива. Итак, на последней итерации значение i станет равным 5.

Поскольку индекс 5 выходит за пределы диапазона чисел, это снова приведет к ArrayIndexOutOfBoundsException :

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

3. Как избежать исключения ArrayIndexOutOfBoundsException ?

Давайте теперь разберемся, как избежать ArrayIndexOutOfBoundsException .

3.1. Запоминание начального индекса

Мы всегда должны помнить, что индекс массива начинается с 0 в Java. Таким образом, первый элемент всегда имеет индекс 0, а последний элемент имеет индекс, на единицу меньший, чем длина массива.

Запоминание этого правила поможет нам избежать ArrayIndexOutOfBoundsException большую часть времени.

3.2. Правильное использование операторов в циклах

Неправильная инициализация переменной цикла с индексом 1 может привести к ArrayIndexOutOfBoundsException .

Точно так же неправильное использование операторов <, <=, > или >= в выражениях завершения циклов является распространенной причиной возникновения этого исключения.

Мы должны правильно определить использование этих операторов в циклах.

3.3. Использование расширенного цикла for

Если наше приложение работает на Java 1.5 или более поздней версии, мы должны использовать расширенный оператор цикла for , специально разработанный для перебора коллекций и массивов. Кроме того, это делает наши циклы более лаконичными и легко читаемыми.

Кроме того, использование расширенного цикла for помогает нам полностью избежать ArrayIndexOutOfBoundsException , поскольку в нем не используется индексная переменная :

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

Здесь нам не нужно беспокоиться об индексации. Расширенный цикл for выбирает элемент и присваивает его переменной цикла number на каждой итерации. Таким образом, он полностью избегает ArrayIndexOutOfBoundsException .

4. IndexOutOfBoundsException и ArrayIndexOutOfBoundsException

IndexOutOfBoundsException возникает, когда мы пытаемся получить доступ к индексу некоторого типа ( строка , массив, список и т. д .) за пределами его диапазона. Это надкласс ArrayIndexOutOfBoundsException и StringIndexOutOfBoundsException .

Подобно ArrayIndexOutOfBoundsException , StringIndexOutOfBoundsException возникает, когда мы пытаемся получить доступ к символу строки с индексом, превышающим ее длину.

5. Вывод

В этой статье мы рассмотрели ArrayIndexOutOfBoundsException , несколько примеров того, как это происходит, и некоторые распространенные методы, чтобы избежать этого.

Как всегда, исходный код всех этих примеров доступен на GitHub.