Qu’est-ce qui cause une exception java.lang.ArrayIndexOutOfBoundsException et comment puis-je l’empêcher?

Que signifie ArrayIndexOutOfBoundsException et comment le supprimer?

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

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

Votre premier port d’escale devrait être la documentation qui l’explique raisonnablement clairement:

Émis pour indiquer qu’un tableau a été accédé avec un index illégal. L’index 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 à savoir comment l’éviter … euh, ne fais pas ça. Soyez prudent avec les index de votre tableau.

Les personnes rencontrent parfois un problème en pensant que les tableaux sont indexés sur 1, par exemple

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

Cela va manquer le premier élément (index 0) et lancer une exception lorsque l'index est égal à 5. Les index valides ici sont compris entre 0 et 4. La déclaration correcte, idiomatique for déclaration ici serait:

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

(En supposant que vous ayez besoin de l'index, bien sûr. Si vous pouvez utiliser la boucle améliorée pour la place, faites-le.)

 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 également:

  • Les tutoriels Java – Bases du langage – Tableaux

Mise à jour : selon votre extrait de code,

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

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

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

Pour le dire brièvement:

Dans la dernière itération de

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

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

Votre code devrait lire

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

Cela signifie que vous essayez d’accéder à un index d’un tableau qui n’est pas valide car il n’est pas entre les limites.

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

 int intArray[] = new int[5]; 

Les programmeurs comptent à partir de zéro. Ainsi, par exemple, lancer une ArrayIndexOutOfBoundsException car la limite supérieure est 4 et non 5.

 intArray[5]; 

Pour éviter une exception hors limite d’index de tableau, il faut utiliser l’instruction améliorée for et où ils peuvent.

La principale motivation (et le cas d’utilisation) est lorsque vous effectuez une itération et que vous n’avez pas besoin d’étapes d’itération compliquées. Vous ne seriez pas en mesure d’utiliser une fonction améliorée for revenir en arrière dans un tableau ou seulement itérer sur tous les autres éléments.

Vous êtes assuré de ne pas manquer d’éléments pour effectuer cette opération, et votre exemple [corrigé] est facilement converti.

Le code ci-dessous:

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

... est équivalent à ceci:

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

Qu’est-ce qui cause ArrayIndexOutOfBoundsException ?

Si vous considérez une variable comme une “boîte” où vous pouvez placer une valeur, un tableau est une série de cases placées l’une à côté de l’autre, où le nombre de cases est un entier fini et explicite.

Créer un tableau comme celui-ci:

 final int[] myArray = new int[5] 

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

Pour récupérer l’une des valeurs de cette série de cases, vous pouvez vous y référer via son index, comme ceci:

 myArray[3] 

Ce qui vous donnera la valeur de la 4ème case de la série (puisque la première case a l’index 0).

Une ArrayIndexOutOfBoundsException est provoquée en essayant de retracer une “boîte” qui n’existe pas, en transmettant un index supérieur à l’index de la dernière “boîte”, ou négatif.

Avec mon exemple en cours d’exécution, ces extraits de code produiraient une telle exception:

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

Comment éviter ArrayIndexOutOfBoundsException

Afin d’empêcher ArrayIndexOutOfBoundsException , il y a quelques points clés à considérer:

En boucle

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

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

Notez le < , ne mélangez jamais un = dedans ..

Vous voudrez peut-être être tenté de faire quelque chose comme ceci:

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

Juste pas. S'en tenir à celui ci-dessus (si vous devez 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 plus à penser aux index.

En boucle, quoi que vous fassiez, ne changez JAMAIS la valeur de l'iterator de boucle (ici: i ). Le seul endroit où cela devrait changer la valeur est de continuer la boucle. Le changer autrement risque de faire exception, et dans la plupart des cas, ce n’est pas 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]; } 

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’objects ssortingng dans votre tableau d’objects ssortingng, à savoir 3, mais vous ne pouvez accéder qu’au name[2] index 2 name[2] , car le tableau est accessible à partir de l’index 0 à name.length - 1 où vous obtenez name.length nombre d’objects.

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

Par exemple:

 Ssortingng[] a={"str1", "str2", str3" ..., "strn"}; for(int i=0;i 

Dans ton cas:

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

Voilà pour cette question simple, mais je voulais juste mettre en évidence une nouvelle fonctionnalité de Java qui évitera toute confusion autour de l’indexation dans les tableaux, même pour les débutants. Java-8 a extrait la tâche de l’itération 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 de l’ ArrayIndexOutOfBoundsException

ArrayIndexOutOfBoundsException signifie que vous essayez d’accéder à un index du tableau qui n’existe pas ou hors de ce tableau. Les index de tableau commencent à 0 et se terminent en longueur – 1 .

Dans ton 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 à l'élément indexé name.length qui n'existe pas (l'index du tableau se termine à la longueur -1). simplement remplacer <= par

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

Le cas le plus courant que j’ai vu pour les ArrayIndexOutOfBoundsExceptions apparemment mystérieuses, c’est-à-dire apparemment pas causé par votre propre code de traitement de tableau, est l’utilisation simultanée de SimpleDateFormat. En particulier dans une 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 dans la méthode SimplateDateFormat.parse (), vous verrez probablement une exception ArrayIndexOutOfBoundsException. Notez la section de synchronisation de la classe javadoc pour SimpleDateFormat .

Assurez-vous qu’il n’y a pas de place dans votre code qui accède de manière concurrente à des classes non sécurisées de thread comme SimpleDateFormat, 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.

Vous obtenez ArrayIndexOutOfBoundsException raison de la partie i<=name.length . name.length renvoie la longueur du name de la chaîne, qui est 3. Par conséquent, lorsque vous essayez d'accéder à name[3] , il est illégal et génère une exception.

Code résolu:

 Ssortingng[] 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 :

La length champ public final , qui contient le nombre de composants du tableau. length peut être positive ou nulle.

Exception d'index de tableau hors limites

C’est comme cela que ce type d’exception a l’air d’être jeté dans Eclipse. Le numéro en rouge indique l’index auquel vous avez tenté d’accéder. Donc, le code ressemblerait à ceci:

 myArray[5] 

L’erreur est renvoyée lorsque vous essayez d’accéder à un index 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 que celui-ci: est hors limites.

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

PS: Si vous cherchez à mieux comprendre les tableaux et à faire des exercices pratiques, voici une vidéo: tutoriel sur les tableaux en Java

Pour votre tableau donné, la longueur du tableau est 3 (ie name.length = 3). Mais comme il stocke les éléments à partir de l’index 0, il a un index max 2.

Donc, au lieu de «i ** <= name.length», vous devez écrire «i <** name.length» pour éviter «ArrayIndexOutOfBoundsException».

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) dont l’index est supérieur à n-1, alors Java lancera ArrayIndexOutOfBoundsException.

Donc, voici deux solutions que nous pouvons utiliser dans un programme

  1. Maintien du compte:

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

    Ou une autre déclaration en 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 se soucier du nombre d'éléments dans le tableau.

     for(Ssortingng str : array) { System.out.println(str); } 

ArrayIndexOutOfBoundsException name lui-même explique que si vous essayez d’accéder à la valeur de l’index qui est hors de la scope de Array, 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 

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

 for(Ssortingng i : name ) System.out.println(i); 

Pour les tableaux multidimensionnels, il peut être difficile de vous 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, de sorte que le bogue subtil est que les boucles centrales et internes utilisent la propriété length de la même dimension (car a[i].length length a[i].length Est la même que la length a[j].length .).

Au lieu de cela, la boucle interne doit utiliser a[i][j].length (ou a[0][0].length a[i][j].length a[0][0].length . Pour simplifier)

Cette erreur se produit à des durées de dépassement de la boucle d’exécution. Considérons un exemple simple comme celui-ci,

 class demo{ public static void main(Ssortingng a[]){ int[] numberArray={4,8,2,3,89,5}; int i; for(i=0;i 

Au début, j'ai initialisé un tableau en tant que "nombreArray". alors, certains éléments de tableau sont imprimés en utilisant pour la boucle. Lorsque la boucle est exécutée 'i', imprimez l'élément (numberArray [i + 1] .. (lorsque la valeur est 1, l'élément numberArray [i + 1] est imprimé.) .. Supposez que, lorsque i = (nombreArray. length-2), le dernier élément du tableau est imprimé..Lorsque la valeur 'i' va à (numberArray.length-1), aucune valeur pour l'impression.Dans ce cas, une exception "ArrayIndexOutOfBoundsException" est survenue. idée.thank!

Selon votre code:

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

Si vous vérifiez System.out.print (name.length);

vous en aurez 3;

cela signifie que la longueur de votre nom est 3

votre boucle tourne de 0 à 3 et devrait être "0 à 2" ou "1 à 3"

Répondre

 Ssortingng[] name = {"tom", "dick", "harry"}; for(int i = 0; i 

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

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

Ou ca:

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