Что вызывает java.ленг.ArrayIndexOutOfBoundsException и как его предотвратить?
Что значит ArrayIndexOutOfBoundsException
mean и как мне избавиться от него?
вот пример кода, который вызывает исключение:
String[] name = {"tom", "dick", "harry"};
for(int i = 0; i<=name.length; i++) {
System.out.print(name[i] +'n');
}
20 ответов
ваш первый порт захода должен быть документация что объясняет это достаточно ясно:
брошенный, чтобы указать, что массив был доступен с недопустимым индексом. Индекс либо отрицательный, либо больше или равен размеру массива.
например:
int[] array = new int[5];
int boom = array[10]; // Throws the exception
Как избежать этого... не делай этого. Будьте осторожны с индексами массива.
одна проблема люди иногда бегают into думает, что массивы 1-индексируются, например
int[] array = new int[5];
// ... populate the array here ...
for (int index = 1; index <= array.length; index++)
{
System.out.println(array[index]);
}
это пропустит первый элемент (индекс 0) и вызовет исключение, когда индекс равен 5. Допустимые индексы здесь 0-4 включительно. Правильный, идиоматический for
утверждение было бы:
for (int index = 0; index < array.length; index++)
(это при условии, что вы нужно индекс, конечно. Если вы можете использовать улучшенный цикл for вместо этого.)
if (index < 0 || index >= array.length) {
// Don't use this index. This is out of bounds (borders, limits, whatever).
} else {
// Yes, you can safely use this index. The index is present in the array.
Object element = array[index];
}
Читайте также:
обновление: согласно вашему фрагменту кода,
for(int i = 0; i<=name.length; i++) {
индекс включает длину массива. Это запрещено. Вам нужно заменить <=
by <
.
for(int i = 0; i < name.length; i++) {
вкратце:
в последней итерации
for(int i = 0; i<=name.length; i++) {
i
будет равна name.length
- незаконной индексов, поскольку индексы массива начинаются с нуля.
ваш код следует читать:
for(int i = 0; i < name.length; i++)
^
это означает, что вы пытаетесь получить доступ к индексу массива, который недействителен, поскольку он не находится между границами.
например, это инициализирует примитивный целочисленный массив с верхней границей 4.
int intArray[] = new int[5];
программисты считают от нуля. Так это например бросит ArrayIndexOutOfBoundsException
поскольку верхняя граница равна 4, а не 5.
intArray[5];
чтобы избежать исключения индекса массива вне границ, следует использовать enhanced -for
заявление, где и когда они могут.
основная мотивация (и вариант использования) - это когда вы выполняете итерацию, и вам не требуются какие-либо сложные шаги итерации. Вы бы не иметь возможность использовать расширенный -for
для перемещения назад в массиве или только итерации по каждому другому элементу.
вы гарантированно не исчерпаете элементы для итерации при этом ваш [исправленный] пример легко преобразуется.
код ниже:
String[] name = {"tom", "dick", "harry"};
for(int i = 0; i< name.length; i++) {
System.out.print(name[i] + "\n");
}
...эквивалентно этому:
String[] name = {"tom", "dick", "harry"};
for(String firstName : name) {
System.out.println(firstName + "\n");
}
какие причины ArrayIndexOutOfBoundsException
?
если вы думаете о переменной как о" коробке", где вы можете разместить значение, то массив представляет собой ряд коробок, расположенных рядом друг с другом, где количество коробок является конечным и явным целым числом.
создать массив такой:
final int[] myArray = new int[5]
создает ряд из 5 коробок, каждая из которых содержит int
. Каждая из коробок имеет индекс, позицию в ряду коробок. Этот индекс начинается с 0 и заканчивается на N-1, где N-размер массива (количество коробок).
чтобы получить одно из значений из этой серии ящиков, вы можете обратиться к нему через его индекс, например:
myArray[3]
что даст вам значение 4-го поля в серии (так как первое поле имеет индекс 0).
An ArrayIndexOutOfBoundsException
вызвано попыткой повторного запуска" коробки", которая не существует, путем передачи индекса, который выше индекса последней" коробки " или отрицательного.
С в моем запущенном примере эти фрагменты кода создадут такое исключение:
myArray[5] //tries to retrieve the 6th "box" when there is only 5
myArray[-1] //just makes no sense
myArray[1337] //waay to high
Как избежать ArrayIndexOutOfBoundsException
для того, чтобы предотвратить ArrayIndexOutOfBoundsException
, есть несколько ключевых пунктов, чтобы рассмотреть:
циклы
при циклическом прохождении через массив всегда убедитесь, что индекс, который вы извлекаете, строго меньше длины массива (количество ящиков). Например:
for (int i = 0; i < myArray.length; i++) {
уведомления the <
, никогда не смешивайте =
там..
возможно, вам захочется сделать что-то вроде этого:
for (int i = 1; i <= myArray.length; i++) {
final int someint = myArray[i - 1]
просто не надо. Придерживайтесь приведенного выше (если вам нужно использовать индекс), и это сэкономит вам много боли.
по возможности используйте foreach:
for (int value : myArray) {
таким образом, вам не придется думать об индексах вообще.
при циклировании, что бы вы ни делали, никогда не изменяйте значение итератора цикла (здесь:i
). Единственное место, где это должно изменить значение, - это сохранить цикл. Изменение его в противном случае просто рискует стать исключением и в большинстве случаев не является необходимым.
извлечение/обновление
при получении произвольного элемента массива всегда проверяйте, является ли он допустимым индексом по длине массива:
public Integer getArrayElement(final int index) {
if (index < 0 || index >= myArray.length) {
return null; //although I would much prefer an actual exception being thrown when this happens.
}
return myArray[index];
}
в вашем коде вы получили доступ к элементам от индекса 0 до длины массива строк. name.length
дает количество строковых объектов в вашем массиве строковых объектов, т. е. 3, но вы можете получить доступ только до индекса 2 name[2]
,
потому что к массиву можно получить доступ от индекса 0 до name.length - 1
где вы получите name.length
количество объектов.
даже при использовании for
цикл вы начали с нулевого индекса, и вы должны закончить с name.length - 1
. В массиве a[n] вы можете получить доступ к форме a[0] для a[n-1].
например:
String[] a={"str1", "str2", str3" ..., "strn"};
for(int i=0;i<a.length()i++)
System.out.println(a[i]);
в вашем случае:
String[] name = {"tom", "dick", "harry"};
for(int i = 0; i<=name.length; i++) {
System.out.print(name[i] +'\n');
}
так много для этого простого вопроса, но я просто хотел выделить новую функцию в Java, которая позволит избежать всех путаниц вокруг индексирования в массивах даже для начинающих. Java-8 абстрагировал задачу итерации для вас.
int[] array = new int[5];
//If you need just the items
Arrays.stream(array).forEach(item -> { println(item); });
//If you need the index as well
IntStream.range(0, array.length).forEach(index -> { println(array[index]); })
в чем выгода? Ну, одна вещь-читаемость, как английский. Во-вторых, вам не нужно беспокоиться о ArrayIndexOutOfBoundsException
ArrayIndexOutOfBoundsException
означает, что вы пытаетесь получить доступ к индексу массива, который не существует или находится вне границы массива. Индексы массива начинаются с 0 и заканчивается на длина - 1.
в вашем случае
for(int i = 0; i<=name.length; i++) {
System.out.print(name[i] +'\n'); // i goes from 0 to length, Not correct
}
ArrayIndexOutOfBoundsException
происходит, когда вы пытаетесь получить доступ
имя.индексированный элемент длины, который не существует (индекс массива заканчивается на длине -1). просто замена
for(int i = 0; i < name.length; i++) {
System.out.print(name[i] +'\n'); // i goes from 0 to length - 1, Correct
}
наиболее распространенным случаем, который я видел для кажущихся таинственными ArrayIndexOutOfBoundsExceptions, т. е., по-видимому, не вызванных вашим собственным кодом обработки массива, является одновременное использование SimpleDateFormat. Особенно в сервлете или контроллере:
public class MyController {
SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy");
public void handleRequest(ServletRequest req, ServletResponse res) {
Date date = dateFormat.parse(req.getParameter("date"));
}
}
Если два потока входят в SimplateDateFormat.метод parse () вместе вы, вероятно, увидите исключение ArrayIndexOutOfBoundsException. Обратите внимание на раздел синхронизации класс javadoc для Класса simpledateformat.
убедитесь, что в коде нет места для доступа к небезопасным классам потоков, таким как SimpleDateFormat, одновременно, как в сервлете или контроллере. Проверьте все переменные экземпляра сервлетов и контроллеров на предмет возможных подозреваемых.
вы получаете ArrayIndexOutOfBoundsException
из-за i<=name.length
часть. name.length
возвращает длину строки name
, то есть 3. Следовательно, когда вы пытаетесь получить доступ name[3]
, это незаконно и бросает исключение.
разрешен код:
String[] name = {"tom", "dick", "harry"};
for(int i = 0; i < name.length; i++) { //use < insteadof <=
System.out.print(name[i] +'\n');
}
это определено в спецификация языка Java:
на
public final
полеlength
, который содержит количество компонентов из массива.length
может быть положительным или нулевым.
вот как выглядит этот тип исключения при запуске в Eclipse. Красное число означает индекс, к которому вы пытались получить доступ. Таким образом, код будет выглядеть так:
myArray[5]
ошибка возникает при попытке получить доступ к индексу, который не существует в массиве. Если массив имеет длину 3,
int[] intArray = new int[3];
тогда единственными допустимыми индексами являются:
intArray[0]
intArray[1]
intArray[2]
если массив имеет длину 1,
int[] intArray = new int[1];
тогда единственным допустимым индексом является:
intArray[0]
любое целое число, равное длине массива или больше его: выходит за рамки.
любое целое число меньше 0: выходит за рамки;
P. S.: Если вы хотите лучше понять массивы и сделать некоторые практические упражнения, есть видео здесь: учебник по массивам в Java
для вашего заданного массива длина массива равна 3 (т. е. имя.длина = 3). Но поскольку он хранит элемент, начинающийся с индекса 0, он имеет максимальный индекс 2.
Итак, вместо ' i**имя.длина' вы должны написать 'я
для любого массива длины n элементы массива будут иметь индекс от 0 до n-1.
Если ваша программа пытается получить доступ к любому элементу (или памяти), имеющему индекс массива больше n-1, то Java бросит ArrayIndexOutOfBoundsException
Так вот два решения, которые мы можем использовать в программе
-
сохранение графа:
for(int count = 0; count < array.length; count++) { System.out.println(array[count]); }
или какой-либо другой оператор цикла как
int count = 0; while(count < array.length) { System.out.println(array[count]); count++; }
-
лучший способ пойти с A для каждого цикла, в этом методе программисту не нужно беспокоиться о количестве элементов в массиве.
for(String str : array) { System.out.println(str); }
ArrayIndexOutOfBoundsException
само имя объясняет, что если вы пытаетесь получить доступ к значению в индексе, который выходит за рамки размера массива, то возникает такое исключение.
в вашем случае вы можете просто удалить знак равенства из цикла for.
for(int i = 0; i<name.length; i++)
лучшим вариантом является итерация массива:
for(String i : name )
System.out.println(i);
для многомерных массивов может быть сложно убедиться, что вы получаете доступ к length
свойство правого измерения. Возьмем для примера следующий код:
int [][][] a = new int [2][3][4];
for(int i = 0; i < a.length; i++){
for(int j = 0; j < a[i].length; j++){
for(int k = 0; k < a[j].length; k++){
System.out.print(a[i][j][k]);
}
System.out.println();
}
System.out.println();
}
каждое измерение имеет разную длину, поэтому тонкая ошибка заключается в том, что средние и внутренние петли используют length
свойство того же измерения (потому что a[i].length
это то же самое, что a[j].length
).
вместо этого внутренний цикл должен использовать a[i][j].length
(или a[0][0].length
, для простоты).
эта ошибка возникает при цикле выполнения overlimit раз.Рассмотрим такой простой пример,
class demo{
public static void main(String a[]){
int[] numberArray={4,8,2,3,89,5};
int i;
for(i=0;i<numberArray.length;i++){
System.out.print(numberArray[i+1]+" ");
}
}
сначала я инициализировал массив как "numberArray". затем некоторые элементы массива печатаются с использованием цикла for. Когда цикл работает " i " время , распечатать (numberArray[i+1] элемент..(когда значение i равно 1, печатается элемент numberArray[i+1].)..Предположим, что, когда i=(numberArray.length-2), печатается последний элемент массива..Когда значение " i " переходит в (numberArray.длина-1) , нет значение для печати..в этой точке происходит "ArrayIndexOutOfBoundsException".Я надеюсь, что вы могли бы получить представление.спасибо !
ArrayIndexOutOfBoundsException всякий раз, когда это исключение приходит, это означает, что вы пытаетесь использовать индекс массива, который выходит за его пределы или в терминах непрофессионала вы запрашиваете больше, чем вы инициализировали.
чтобы предотвратить это, убедитесь, что вы не просите индекс которых нет в массиве, т. е. если длина массива равна 10, то ваш показатель должен находиться в диапазоне от 0 до 9
согласно вашему коду:
String[] name = {"tom", "dick", "harry"};
for(int i = 0; i<=name.length; i++) {
System.out.print(name[i] +'\n');
}
Если вы проверить Система.из.печать(имя.длина);
вы получите 3;
это означает, что длина вашего имени составляет 3
ваш цикл выполняется от 0 до 3 который должен работать либо "от 0 до 2", либо "от 1 до 3"
ответ
String[] name = {"tom", "dick", "harry"};
for(int i = 0; i<name.length; i++) {
System.out.print(name[i] +'\n');
}
вы не можете повторять или хранить больше данных, чем длина вашего массива. В этом случае вы можете сделать следующее:
for (int i = 0; i <= name.length - 1; i++) {
// ....
}
или такой:
for (int i = 0; i < name.length; i++) {
// ...
}