Che cosa causa un java.lang.ArrayIndexOutOfBoundsException e come faccio a prevenirlo?


Cosa significa ArrayIndexOutOfBoundsException e come posso liberarmene?

Ecco un esempio di codice che attiva l'eccezione:

String[] name = {"tom", "dick", "harry"};
for(int i = 0; i<=name.length; i++) {
  System.out.print(name[i] +'\n');
}
Author: Infinite Recursion, 2011-04-05

20 answers

Il tuo primo porto di scalo dovrebbe essere la documentazione che lo spiega ragionevolmente chiaramente:

Generato per indicare che a un array è stato effettuato l'accesso con un indice illegale. L'indice è negativo o maggiore o uguale alla dimensione dell'array.

Quindi per esempio:

int[] array = new int[5];
int boom = array[10]; // Throws the exception

Per quanto riguarda come evitarlo... non farlo. Fai attenzione con i tuoi indici di array.

Un problema in cui le persone a volte si imbattono è pensare che gli array siano 1-indicizzato, ad esempio

int[] array = new int[5];
// ... populate the array here ...
for (int index = 1; index <= array.length; index++)
{
    System.out.println(array[index]);
}

Che perderà il primo elemento (indice 0) e genererà un'eccezione quando l'indice è 5. Gli indici validi qui sono 0-4 inclusi. L'istruzione for corretta e idiomatica qui sarebbe:

for (int index = 0; index < array.length; index++)

(Questo presuppone che tuabbia bisogno di l'indice, ovviamente. Se invece è possibile utilizzare il ciclo for avanzato, farlo.)

 222
Author: Jon Skeet, 2015-10-16 21:38:26
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];
}

Vedi anche:


Aggiorna: secondo il tuo frammento di codice,

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

L'indice include la lunghezza dell'array. Questo è fuori dai limiti. È necessario sostituire <= con <.

for(int i = 0; i < name.length; i++) {
 39
Author: BalusC, 2011-04-05 16:12:08

Per dirla in breve:

Nell'ultima iterazione di

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

i sarà uguale a name.length che è un indice illegale, poiché gli indici di array sono basati su zero.

Il tuo codice dovrebbe leggere

for(int i = 0; i < name.length; i++) 
                 ^
 16
Author: aioobe, 2015-10-29 03:05:33

Significa che si sta tentando di accedere a un indice di un array che non è valido in quanto non è tra i limiti.

Ad esempio questo inizializzerebbe un array intero primitivo con il limite superiore 4.

int intArray[] = new int[5];

I programmatori contano da zero. Quindi questo ad esempio genererebbe un ArrayIndexOutOfBoundsException poiché il limite superiore è 4 e non 5.

intArray[5];
 11
Author: Octavian Damiean, 2011-04-05 16:01:31

Per evitare un'eccezione out-of-bounds dell'indice di matrice, si dovrebbe usare enhanced-for dichiarazione dove e quando possono.

La motivazione principale (e il caso d'uso) è quando si esegue l'iterazione e non si richiedono passaggi di iterazione complicati. Si dovrebbe non essere in grado di utilizzare un enhanced-for per spostarsi all'indietro in un array o solo iterare su ogni altro elemento.

Hai la garanzia di non esaurire gli elementi da iterare quando lo fai, e il tuo [corretto] esempio è facilmente convertito sopra.

Il seguente codice:

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

Equivalent è equivalente a questo:

String[] name = {"tom", "dick", "harry"};
for(String firstName : name) {
    System.out.println(firstName + "\n");
}
 6
Author: Makoto, 2015-10-19 11:00:18

Quali sono le cause ArrayIndexOutOfBoundsException?

Se si pensa a una variabile come a una "casella" in cui è possibile inserire un valore, allora un array è una serie di caselle poste l'una accanto all'altra, dove il numero di caselle è un numero intero finito ed esplicito.

Creazione di un array come questo:

final int[] myArray = new int[5]

Crea una fila di 5 caselle, ciascuna contenente un int. Ciascuna delle caselle ha un indice, una posizione nella serie di caselle. Questo indice inizia da 0 e termina a N-1, dove N è la dimensione dell'array (il numero di caselle).

Per recuperare uno dei valori da questa serie di caselle, è possibile fare riferimento ad esso attraverso il suo indice, in questo modo:

myArray[3]

Che ti darà il valore della 4a casella della serie (poiché la prima casella ha indice 0).

Un ArrayIndexOutOfBoundsException è causato dal tentativo di ripristinare una "casella" che non esiste, passando un indice superiore all'indice dell'ultima "casella" o negativo.

Con il mio esempio in esecuzione, questi frammenti di codice produrrebbero un tale eccezione:

myArray[5] //tries to retrieve the 6th "box" when there is only 5
myArray[-1] //just makes no sense
myArray[1337] //waay to high

Come evitare ArrayIndexOutOfBoundsException

Al fine di prevenire ArrayIndexOutOfBoundsException, ci sono alcuni punti chiave da considerare:

Ciclo

Quando si esegue il loop di un array, assicurarsi sempre che l'indice che si sta recuperando sia strettamente inferiore alla lunghezza dell'array (il numero di caselle). Ad esempio:

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

Nota il <, non mescolare mai un = lì dentro..

Si potrebbe desiderare di essere tentati di fare qualcosa di simile questo:

for (int i = 1; i <= myArray.length; i++) {
    final int someint = myArray[i - 1]

Non farlo. Attenersi a quello sopra (se è necessario utilizzare l'indice) e ti farà risparmiare un sacco di dolore.

Ove possibile, usare foreach:

for (int value : myArray) {

In questo modo non dovrai pensare affatto agli indici.

Durante il ciclo, qualunque cosa tu faccia, NON cambiare MAI il valore dell'iteratore del ciclo (qui: i). L'unico posto in cui questo dovrebbe cambiare valore è quello di mantenere il ciclo in corso. Cambiarlo altrimenti rischia solo un'eccezione, e nella maggior parte dei casi no necessario.

Recupero / aggiornamento

Quando si recupera un elemento arbitrario dell'array, verificare sempre che sia un indice valido rispetto alla lunghezza dell'array:

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];
}
 6
Author: Tobb, 2017-02-03 13:20:53

Nel codice è stato effettuato l'accesso agli elementi dall'indice 0 alla lunghezza dell'array di stringhe. name.length fornisce il numero di oggetti string nel tuo array di oggetti string cioè 3, ma puoi accedere solo fino all'indice 2 name[2], perché è possibile accedere all'array dall'indice 0 a name.length - 1 dove si ottiene name.length numero di oggetti.

Anche durante l'utilizzo di un ciclo for hai iniziato con index zero e dovresti terminare con name.length - 1. In un array a [n] è possibile accedere al modulo a[0] a a[n-1].

Per esempio:

String[] a={"str1", "str2", str3" ..., "strn"};

for(int i=0;i<a.length()i++)
    System.out.println(a[i]);

Nel tuo caso:

String[] name = {"tom", "dick", "harry"};

for(int i = 0; i<=name.length; i++) {
    System.out.print(name[i] +'\n');
}
 3
Author: Madhusudan chowdary, 2017-12-17 10:03:21

Tanto per questa semplice domanda, ma volevo solo evidenziare una nuova funzionalità in Java che eviterà tutte le confusioni sull'indicizzazione negli array anche per i principianti. Java-8 ha astratto il compito di iterare per te.

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]); })

Qual è il vantaggio? Bene, una cosa è la leggibilità come l'inglese. In secondo luogo, non è necessario preoccuparsi del ArrayIndexOutOfBoundsException

 1
Author: Satyendra Kumar, 2017-10-25 07:38:27

ArrayIndexOutOfBoundsException significa che si sta tentando di accedere a un indice della matrice che non esiste o fuori dal limite di questa matrice. Gli indici degli array iniziano da 0 e termina a lunghezza-1 .

Nel tuo caso

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

ArrayIndexOutOfBoundsException accade quando si sta tentando di accedere nome.elemento indicizzato di lunghezza che non esiste (l'indice dell'array termina alla lunghezza -1). la semplice sostituzione di

for(int i = 0; i < name.length; i++) {
    System.out.print(name[i] +'\n');  // i goes from 0 to length - 1, Correct
}
 1
Author: adn.911, 2017-11-30 16:41:17

Il caso più comune che ho visto per ArrayIndexOutOfBoundsExceptions apparentemente misterioso, cioè apparentemente non causato dal proprio codice di gestione dell'array, è l'uso simultaneo di SimpleDateFormat. In particolare in un servlet o controller:

public class MyController {
  SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy");

  public void handleRequest(ServletRequest req, ServletResponse res) {
    Date date = dateFormat.parse(req.getParameter("date"));
  }
}

Se due thread entrano in SimplateDateFormat.metodo parse () insieme probabilmente vedrai un ArrayIndexOutOfBoundsException. Si noti la sezione di sincronizzazione della classe javadoc per SimpleDateFormat .

Assicurarsi che ci sia nessun posto nel codice che accede a classi thread non sicure come SimpleDateFormat in modo simultaneo come in un servlet o controller. Controlla tutte le variabili di istanza dei tuoi servlet e controller per probabili sospetti.

 1
Author: Kyri Sarantakos, 2017-12-17 09:54:34

Stai ricevendo ArrayIndexOutOfBoundsException a causa della parte i<=name.length. name.length restituisce la lunghezza della stringa name, che è 3. Quindi quando si tenta di accedere a name[3], è illegale e genera un'eccezione.

Codice risolto:

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

È definito nella specifica del linguaggio Java :

Il campo public final length, che contiene il numero di componenti della matrice. length può essere positivo o zero.

 1
Author: roottraveller, 2017-12-17 10:00:09

Indice di matrice fuori dai limiti eccezione

Ecco come appare questo tipo di eccezione quando viene lanciato in Eclipse. Il numero in rosso indica l'indice a cui si è tentato di accedere. Quindi il codice sarebbe simile a questo:

myArray[5]

L'errore viene generato quando si tenta di accedere a un indice che non esiste in quell'array. Se un array ha una lunghezza di 3,

int[] intArray = new int[3];

Quindi gli unici indici validi sono:

intArray[0]
intArray[1]
intArray[2]

Se una matrice ha una lunghezza di 1,

int[] intArray = new int[1];

Quindi l'unico indice valido è:

intArray[0]

Qualsiasi intero uguale alla lunghezza dell'array, o più grande di esso: è fuori dai limiti.

Qualsiasi numero intero inferiore a 0: è fuori dai limiti;

POST scriptum: Se si cerca di avere una migliore comprensione degli array e fare alcuni esercizi pratici, c'è un video qui: tutorial sugli array in Java

 1
Author: Ion, 2017-12-17 10:02:04

Per l'array dato la lunghezza dell'array è 3 (cioè nome.lunghezza = 3). Ma poiché memorizza l'elemento a partire dall'indice 0, ha un indice massimo 2.

Quindi, invece di 'i** nome.lunghezza 'dovresti scrivere' i

 1
Author: nIKHIL, 2018-01-16 12:13:33

Per qualsiasi array di lunghezza n, gli elementi dell'array avranno un indice da 0 a n-1.

Se il tuo programma sta tentando di accedere a qualsiasi elemento (o memoria) con indice di array maggiore di n-1, Java genererà ArrayIndexOutOfBoundsException

Quindi ecco due soluzioni che possiamo usare in un programma

  1. Mantenimento del conteggio:

    for(int count = 0; count < array.length; count++) {
        System.out.println(array[count]);
    }
    

    O qualche altra istruzione di loop come

    int count = 0;
    while(count < array.length) {
        System.out.println(array[count]);
        count++;
    }
    
  2. Un modo migliore vai con a per ciascuno loop, in questo metodo un programmatore non ha bisogno di preoccuparsi del numero di elementi nell'array.

    for(String str : array) {
        System.out.println(str);
    }
    
 0
Author: Mohit, 2017-12-17 09:58:06

ArrayIndexOutOfBoundsException il nome stesso spiega che se si tenta di accedere al valore all'indice che è fuori dall'ambito della dimensione dell'array, si verifica questo tipo di eccezione.

Nel tuo caso, puoi semplicemente rimuovere il segno di uguale dal tuo ciclo for.

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

L'opzione migliore è quella di iterare un array:

for(String i : name )
      System.out.println(i);
 0
Author: Madhusudan Sharma, 2018-05-17 03:46:58

Per gli array multidimensionali, può essere difficile assicurarsi di accedere alla proprietà length della giusta dimensione. Prendi ad esempio il seguente codice:

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();
}

Ogni dimensione ha una lunghezza diversa, quindi il bug sottile è che i loop centrale e interno usano la proprietà length della stessa dimensione (perché a[i].length è uguale a a[j].length).

Invece, il ciclo interno dovrebbe usare a[i][j].length (o a[0][0].length, per semplicità).

 0
Author: Bill the Lizard, 2018-06-12 19:41:38

Questo errore si verifica nei tempi di overlimit del ciclo di esecuzione.Consideriamo un semplice esempio come questo,

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]+"  ");
    }
}

All'inizio, ho inizializzato un array come 'numberArray'. quindi, alcuni elementi dell'array vengono stampati usando for loop. Quando loop esegue il tempo 'i', stampa l'elemento (numberArray[i+1]..(quando il valore i è 1, viene stampato l'elemento numberArray[i+1].)..Supponiamo che, quando i=(numberArray.length-2), viene stampato l'ultimo elemento dell'array..Quando il valore ' i ' va a (numberArray.lunghezza-1), nessun valore per printing..In quel punto,' ArrayIndexOutOfBoundsException ' si verifica.Spero che tu possa avere un'idea.Grazie!

 0
Author: GT_hash, 2018-07-17 03:03:45

ArrayIndexOutOfBoundsException ogni volta che arriva questa eccezione significa che stai cercando di utilizzare un indice di array che è fuori dai suoi limiti o in termini laici stai richiedendo più di quanto hai inizializzato.

Per evitare ciò assicurati sempre di non richiedere un indice che non è presente nell'array, ovvero se la lunghezza dell'array è 10, l'indice deve variare da 0 a 9

 0
Author: sgrpwr, 2018-09-15 10:29:18

Secondo il tuo codice :

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

Se si controlla Sistema.fuori.stampa (nome.lunghezza);

Otterrai 3;

Significa che la lunghezza del tuo nome è 3

Il tuo ciclo è in esecuzione da 0 a 3 che dovrebbe essere in esecuzione "0 a 2" o "1 a 3"

Risposta

String[] name = {"tom", "dick", "harry"};
for(int i = 0; i<name.length; i++) {
  System.out.print(name[i] +'\n');
}
 -1
Author: Abhishek Agarwal, 2018-03-26 10:16:00

Non è possibile iterare o memorizzare più dati della lunghezza dell'array. In questo caso potresti fare così:

for (int i = 0; i <= name.length - 1; i++) {
    // ....
}

O questo:

for (int i = 0; i < name.length; i++) {
    // ...
}
 -3
Author: Kevin7, 2017-12-17 09:55:16