Quali sono le cause ArrayIndexOutOfBoundsException
?
Se si considera una variabile come una "casella" in cui è possibile posizionare un valore, una matrice è una serie di caselle poste una accanto all'altra, in cui il numero di caselle è un numero intero finito ed esplicito.
Creazione di un array come questo:
final int[] myArray = new int[5]
crea una riga di 5 caselle, ognuna contenente un int
. Ciascuna delle caselle ha un indice, una posizione nella serie di caselle. Questo indice inizia da 0 e termina in N-1, dove N è la dimensione dell'array (il numero di caselle).
Per recuperare uno dei valori da questa serie di caselle, puoi fare riferimento ad esso attraverso il suo indice, in questo modo:
myArray[3]
Il che ti darà il valore della quarta casella della serie (poiché la prima casella ha un indice 0).
Un ArrayIndexOutOfBoundsException
è causato dal tentativo di recuperare una "scatola" che non esiste, passando un indice che è superiore all'indice dell'ultima "scatola", o negativo.
Con il mio esempio corrente, questi frammenti di codice genererebbero 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
Per prevenire ArrayIndexOutOfBoundsException
, ci sono alcuni punti chiave da considerare:
looping
Quando si esegue il ciclo in un array, assicurarsi sempre che l'indice che si sta recuperando sia strettamente più piccolo della lunghezza dell'array (il numero di caselle). Per esempio:
for (int i = 0; i < myArray.length; i++) {
Notare il <
, mai mescolare un =
dentro ..
Potresti essere tentato di fare qualcosa del genere:
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 molto dolore.
Ove possibile, utilizzare foreach:
for (int value : myArray) {
In questo modo non dovrai assolutamente pensare agli indici.
Durante il loop, qualunque cosa tu faccia, MAI cambiare il valore dell'iteratore di loop (qui:) i
. L'unico posto in cui ciò dovrebbe cambiare valore è quello di mantenere il ciclo attivo. Altrimenti cambiarlo è solo rischiare un'eccezione, e nella maggior parte dei casi non è necessario.
Retrieval / 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];
}