Что вызывает исключение java.lang.ArrayIndexOutOfBoundsException и как его предотвратить? - PullRequest
264 голосов
/ 05 апреля 2011

Что означает ArrayIndexOutOfBoundsException и как от него избавиться?

Вот пример кода, который вызывает исключение:

String[] name = { "tom", "dick", "harry" };
for (int i = 0; i <= name.length; i++) {
    System.out.println(name[i]);
}

Ответы [ 24 ]

3 голосов
/ 25 октября 2017

Так много для этого простого вопроса, но я просто хотел выделить новую функцию в 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

2 голосов
/ 14 декабря 2018

ArrayIndexOutOfBounds означает, что вы пытаетесь проиндексировать позицию в массиве, который не выделен.

В этом случае:

String[] name = { "tom", "dick", "harry" };
for (int i = 0; i <= name.length; i++) {
    System.out.println(name[i]);
}
  • name.length равно 3, так как массивбыло определено с 3 объектами String.
  • При доступе к содержимому массива позиция начинается с 0. Так как есть 3 элемента, это будет означать name [0] = "tom", name [1] ="dick" и name [2] = "harry
  • Когда вы зацикливаетесь, поскольку i может быть меньше или равно name.length, вы пытаетесь получить доступ к имени [3], котороенедоступно.

Чтобы обойти это ...

  • В вашем цикле for вы можете сделать i

    for(int i = 0; i<name.length; i++)

  • Использовать a для каждого цикла

    String[] name = { "tom", "dick", "harry" }; for(String n : name) { System.out.println(n); }

  • Использовать list.forEach (действие потребителя) (требуется Java8)

    String[] name = { "tom", "dick", "harry" }; Arrays.asList(name).forEach(System.out::println);

  • Преобразовать массив в поток - этоэто хороший вариант, если вы хотите выполнитьдополнительные «операции» с вашим массивом, например, фильтрация, преобразование текста, преобразование в карту и т. д. (требуется Java8)

    String[] name = { "tom", "dick", "harry" }; --- Arrays.asList(name).stream().forEach(System.out::println); --- Stream.of(name).forEach(System.out::println);

2 голосов
/ 05 апреля 2011

Наиболее распространенным случаем, который я видел для, казалось бы, загадочных 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, одновременно, как в сервлете или контроллере,Проверьте все переменные экземпляра ваших сервлетов и контроллеров на наличие возможных подозреваемых.

2 голосов
/ 15 сентября 2018

ArrayIndexOutOfBoundsException всякий раз, когда возникает это исключение, это означает, что вы пытаетесь использовать индекс массива, который находится за его пределами или в терминах непрофессионала, вы запрашиваете больше, чем вы инициализировали.

Во избежание этого всегда убедитесь, что вы не запрашиваете индекс, которого нет в массиве, т.е. если длина массива равна 10, тогда ваш индекс должен находиться в диапазоне от 0 до 9

2 голосов
/ 12 июня 2018

Для многомерных массивов может быть сложно получить доступ к свойству 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, для простоты).

1 голос
/ 12 апреля 2019

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

1 голос
/ 13 ноября 2018

Здесь я вижу ответы на все вопросы, объясняющие, как работать с массивами и как избежать исключения индекса за пределами границ.Я лично избегаю массивов любой ценой.Я использую классы Collections, что исключает всю глупость необходимости полностью разбираться с индексами массивов.Циклические конструкции прекрасно работают с коллекциями, поддерживающими код, который легче писать, понимать и поддерживать.

1 голос
/ 18 октября 2018

Каждый элемент в массиве называется элементом, и каждый элемент доступен по его числовому индексу.Как показано на предыдущем рисунке, нумерация начинается с 0 .Следовательно, к 9-му элементу, например, должен быть получен доступ по индексу 8.

Выдается исключение IndexOutOfBoundsException, указывающее, что индекс какого-либо вида (например, массив, строка или вектор) отсутствуетдиапазона.

Доступ к любому массиву X возможен от [0 до (X.length - 1)]

1 голос
/ 26 марта 2018

Согласно вашему коду:

String[] name = {"tom", "dick", "harry"};
for(int i = 0; i<=name.length; i++) {
  System.out.print(name[i] +'\n');
}

Если вы проверите System.out.print (name.length);

вы получите 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');
}
1 голос
/ 30 ноября 2017

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 происходит, когда вы пытаетесь получить доступ индексированный элемент name.length, который не существует (индекс массива заканчивается длиной -1). просто замена <= на <решит эту проблему. </p>

for(int i = 0; i < name.length; i++) {
    System.out.print(name[i] +'\n');  // i goes from 0 to length - 1, Correct
}
...