Які причини ArrayIndexOutOfBoundsException
?
Якщо ви думаєте про змінну як "поле", куди ви можете розмістити значення, то масив - це низка полів, розміщених поруч з іншими, де кількість коробок є кінцевим і явним цілим числом.
Створення такого масиву:
final int[] myArray = new int[5]
створює ряд з 5 ящиків, у кожному з яких є int
. Кожна з коробок має покажчик, позицію в серії коробок. Цей індекс починається з 0 і закінчується на N-1, де N - розмір масиву (кількість полів).
Щоб отримати одне із значень із цієї серії вікон, ви можете посилатися на нього через його індекс, наприклад:
myArray[3]
Що дасть вам значення 4-го вікна в серії (оскільки перший ящик має індекс 0).
A 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++) {
Зауважте <
, ніколи не змішуйте =
там.
Можливо, вам захочеться спокуси зробити щось подібне:
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];
}