Qu'est-ce qui cause un java.lang.ArrayIndexOutOfBoundsException et comment l'empêcher?


Que signifie ArrayIndexOutOfBoundsException et comment puis-je m'en débarrasser?

Voici un exemple de code qui déclenche l'exception:

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

Votre première escale devrait être la documentation {[6] } qui l'explique raisonnablement clairement:

Lancé pour indiquer qu'un tableau a été accédé avec un index illégal. L'indice est négatif ou supérieur ou égal à la taille du tableau.

Donc par exemple:

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

Quant à la façon de l'éviter... euh, ne le faites pas. Soyez prudent avec vos index de tableau.

Un problème que les gens rencontrent parfois est de penser que les tableaux sont 1-indexé, par exemple

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

Qui manquera le premier élément (index 0) et lancera une exception lorsque l'index est 5. Les index valides ici sont 0-4 inclus. La déclaration correcte et idiomatique for ici serait:

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

(Cela suppose que vous avez besoin de l'index, bien sûr. Si vous pouvez utiliser la boucle for améliorée à la place, faites-le.)

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

Voir aussi:


Mise à Jour: selon votre extrait de code,

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

L'index inclut la longueur du tableau. Ce qui est hors des limites. Vous devez remplacer <= par <.

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

Pour le dire brièvement:

Dans la dernière itération de

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

i sera égal à name.length qui est un index illégal, puisque les indices de tableau sont basés sur zéro.

Votre code devrait lire

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

Cela signifie que vous essayez d'accéder à un index d'un tableau qui n'est pas valide car elle n'est pas entre les bornes.

Par exemple, cela initialiserait un tableau entier primitif avec la borne supérieure 4.

int intArray[] = new int[5];

Les programmeurs comptent à partir de zéro. Donc, ceci par exemple lancerait un ArrayIndexOutOfBoundsException car la limite supérieure est 4 et non 5.

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

Pour éviter une exception hors limites d'index de tableau, il faut utiliser le enhanced-for déclaration où et quand ils le peuvent.

La motivation principale (et le cas d'utilisation) est lorsque vous itérez et que vous n'avez besoin d'aucune étape d'itération compliquée. Vous ne pouvez pas utiliser un-foramélioré pour revenir en arrière dans un tableau ou uniquement itérer sur tous les autres éléments.

Vous êtes assuré de ne pas manquer d'éléments à parcourir lors de cette opération, et votre l'exemple [corrigé]est facilement converti.

Le code ci-dessous:

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

...est équivalent à ceci:

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

Quelles sont les causes de ArrayIndexOutOfBoundsException?

Si vous pensez à une variable comme une "boîte" où vous pouvez placer une valeur, un tableau est une série de boîtes placées à côté de l'autre, où le nombre de boîtes est finie et explicite entier.

Créer un tableau comme ceci:

final int[] myArray = new int[5]

Crée une rangée de 5 cases, chacune contenant un int. Chacune des boîtes a un index, une position dans la série de boîtes. Cet index commence à 0 et se termine à N-1, où N est la taille du tableau (le nombre de boîtes).

Pour récupérer une des valeurs de cette série de boîtes, vous pouvez vous y référer via son index, comme ceci:

myArray[3]

Qui vous donnera la valeur de la 4ème boîte de la série (puisque la première boîte a l'index 0).

Un ArrayIndexOutOfBoundsException est provoqué en essayant de récupérer une "boîte" qui n'existe pas, en passant un indice supérieur à l'indice de la dernière "boîte", ou négatif.

Avec mon exemple en cours d'exécution, ces extraits de code produiraient un tel exception:

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

Comment éviter ArrayIndexOutOfBoundsException

, afin de prévenir ArrayIndexOutOfBoundsException, il existe quelques points clés à considérer:

Boucle

Lorsque vous parcourez un tableau, assurez-vous toujours que l'index que vous récupérez est strictement inférieur à la longueur du tableau (le nombre de boîtes). Par exemple:

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

Remarquez le <, ne mélangez jamais un = là-dedans..

, Vous pourriez être tenté de faire quelque chose comme ceci:

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

Ne le faites pas. Tenez-vous à celui ci-dessus (si vous avez besoin d'utiliser l'index) et cela vous évitera beaucoup de douleur.

Dans la mesure du possible, utilisez foreach:

for (int value : myArray) {

De cette façon, vous n'aurez pas du tout à penser aux index.

Lors de la boucle, quoi que vous fassiez, ne changez JAMAIS la valeur de l'itérateur de boucle (ici: i). Le seul endroit où cela devrait changer de valeur est de continuer la boucle. Le changer autrement, c'est simplement risquer une exception, et dans la plupart des cas, ce n'est pas le cas nécessaire.

Récupération/mise à jour

Lors de la récupération d'un élément arbitraire du tableau, vérifiez toujours qu'il s'agit d'un index valide par rapport à la longueur du tableau:

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

Dans votre code, vous avez accédé aux éléments de l'index 0 à la longueur du tableau de chaînes. name.length donne le nombre d'objets string dans votre tableau d'objets string c'est à dire 3, mais vous pouvez accéder uniquement à l'index 2 name[2], parce que le tableau est accessible de l'index 0 à name.length - 1 où vous obtenez name.length nombre d'objets.

Même en utilisant une boucle for, vous avez commencé avec l'index zéro et vous devriez terminer avec name.length - 1. Dans un tableau a[n], vous pouvez accéder à la forme a[0] a[n-1].

Pour exemple:

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

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

Dans votre cas:

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

Voilà pour cette question simple, mais je voulais juste mettre en évidence une nouvelle fonctionnalité en Java qui évitera toutes les confusions autour de l'indexation dans les tableaux, même pour les débutants. Java - 8 a résumé la tâche d'itérer pour vous.

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

Quel est l'avantage? Eh bien, une chose est la lisibilité comme l'anglais. Deuxièmement, vous n'avez pas à vous soucier du ArrayIndexOutOfBoundsException

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

ArrayIndexOutOfBoundsException signifie que vous essayez d'accéder à un index du tableau qui n'existe pas ou en dehors de la limite de ce tableau. Les indices de tableau commencent à partir de 0 et à la fin à longueur - 1.

Dans votre cas,

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

ArrayIndexOutOfBoundsException se produit lorsque vous essayez d'accéder à nom.élément indexé de longueur qui n'existe pas (l'index du tableau se termine à la longueur -1). le simple remplacement de

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

Le cas le plus courant que j'ai vu pour ArrayIndexOutOfBoundsExceptions apparemment mystérieux, c'est-à-dire apparemment non causé par votre propre code de gestion de tableau, est l'utilisation simultanée de SimpleDateFormat. En particulier dans un servlet ou un contrôleur:

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

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

Si deux threads entrent le SimplateDateFormat.parse () méthode ensemble, vous verrez probablement une ArrayIndexOutOfBoundsException. Notez la section synchronisation de la classe javadoc pour SimpleDateFormat .

Assurez-vous qu'il est aucun endroit dans votre code qui accède à des classes dangereuses de thread comme SimpleDateFormat de manière simultanée comme dans un servlet ou un contrôleur. Vérifiez toutes les variables d'instance de vos servlets et contrôleurs pour les suspects probables.

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

Vous obtenez ArrayIndexOutOfBoundsException en raison de i<=name.length partie. name.length retourne la longueur de la chaîne name, qui est de 3. Par conséquent, lorsque vous essayez d'accéder à name[3], c'est illégal et lève une exception.

Code résolu:

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

Il est défini dans la spécification du langage Java :

Le champ public final length, qui contient le nombre de composants de la matrice. length peut être positif ou nul.

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

Index de tableau hors limites exception

Voilà à quoi ressemble ce type d'exception lorsqu'il est lancé dans Eclipse. Le numéro en rouge indique l'index auquel vous avez essayé d'accéder. Donc, le code ressemblerait à ceci:

myArray[5]

L'erreur est générée lorsque vous essayez d'accéder à un indice qui n'existe pas dans ce tableau. Si un tableau a une longueur de 3,

int[] intArray = new int[3];

Alors les seuls index valides sont:

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

Si un tableau a une longueur de 1,

int[] intArray = new int[1];

Alors le seul index valide est:

intArray[0]

Tout entier égal à la longueur du tableau, ou plus grand qu'il: est hors limites.

Tout entier inférieur à 0: est hors limites;

P.S.: Si vous cherchez à mieux comprendre les tableaux et à faire quelques exercices pratiques, il y a une vidéo ici: tutoriel sur les tableaux en Java

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

Pour votre tableau donné, la longueur du tableau est 3(c'est-à-dire name.longueur = 3). Mais comme il stocke l'élément à partir de l'indice 0, on a max indice 2.

Donc, au lieu de " i**nom.longueur 'vous devriez écrire' i

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

Pour tout tableau de longueur n, les éléments du tableau auront un index de 0 à n-1.

Si votre programme essaie d'accéder à un élément (ou à une mémoire) ayant un index de tableau supérieur à n-1, Java lancera ArrayIndexOutOfBoundsException

Voici Donc deux solutions que nous pouvons utiliser dans un programme

  1. Maintien du nombre:

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

    Ou une autre instruction de boucle comme

    int count = 0;
    while(count < array.length) {
        System.out.println(array[count]);
        count++;
    }
    
  2. Une meilleure façon d'aller avec un pour chaque boucle, dans cette méthode, un programmeur n'a pas besoin de s'embêter sur le nombre d'éléments dans le tableau.

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

ArrayIndexOutOfBoundsException le nom lui-même explique que si vous essayez d'accéder à la valeur de l'index qui est hors de la portée de la taille du tableau, ce type d'exception se produit.

Dans votre cas, Vous pouvez simplement supprimer le signe égal de votre boucle for.

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

La meilleure option est d'itérer un tableau:

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

Pour les tableaux multidimensionnels, il peut être difficile de s'assurer que vous accédez à la propriété length de la bonne dimension. Prenez le code suivant par exemple:

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

Chaque dimension a une longueur différente, donc le bogue subtil est que les boucles centrale et intérieure utilisent la propriété length de la même dimension (car a[i].length est identique à a[j].length).

Au lieu de cela, la boucle interne devrait utiliser a[i][j].length (ou a[0][0].length, pour plus de simplicité).

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

Cette erreur se produit lors des temps de dépassement de la boucle d'exécution.Considérons un exemple simple comme celui-ci,

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

Au début, j'ai initialisé un tableau en tant que 'numberArray'. ensuite, certains éléments de tableau sont imprimés en utilisant for loop. Lorsque la boucle est en cours d'exécution, imprimez l'élément (numberArray [i + 1]..(lorsque la valeur i est 1, l'élément numberArray[i+1] est imprimé.)..Supposons que, quand i=(numberArray.longueur-2), dernier élément du tableau est imprimé..Lorsque la valeur ' i ' va à (numberArray.longueur-1) , aucune valeur pour printing..In ce point, 'ArrayIndexOutOfBoundsException' se produit.J'espère que vous pourrait se faire une idée.merci!!!!

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

ArrayIndexOutOfBoundsException chaque fois que cette exception arrive, cela signifie que vous essayez d'utiliser un index de tableau qui est hors de ses limites ou en termes simples, vous demandez plus que ce que vous avez initialisé.

Pour éviter cela, assurez-vous toujours que vous ne demandez pas un index qui n'est pas présent dans le tableau, c'est-à-dire si la longueur du tableau est 10, votre index doit être compris entre 0 et 9

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

Selon votre code:

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

Si Vous cochez Système.hors.print(nom.la longueur);

, Vous obtiendrez 3;

Cela signifie que la longueur de votre nom est 3

Votre boucle s'exécute de 0 à 3 qui devrait être exécuté soit "0 à 2" ou "1 à 3"

Réponse

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

Vous ne pouvez pas itérer ou stocker plus de données que la longueur de votre tableau. Dans ce cas, vous pouvez faire comme ceci:

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

Ou ceci:

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