IndexOutOfBoundsException în Java

Apare când folosești o poziție inexistentă: list.get(5) într-o listă de 3 elemente sau un indice negativ.

Sintaxă
public class IndexOutOfBoundsException extends RuntimeException

ArrayIndexOutOfBoundsException   // tablouri
StringIndexOutOfBoundsException  // String.charAt, substring
Objects.checkIndex(indice, lungime)

Ce face IndexOutOfBoundsException

Pozițiile încep de la 0, deci ultima poziție validă este lungime - 1. Orice indice negativ sau mai mare sau egal cu lungimea aruncă IndexOutOfBoundsException, cu un mesaj ca Index 3 out of bounds for length 3.

Are două subclase: ArrayIndexOutOfBoundsException pentru tablouri și StringIndexOutOfBoundsException pentru String (charAt, substring). ArrayList.get aruncă direct IndexOutOfBoundsException (listele create cu List.of pot arunca subclasa pentru tablouri). Prinzând clasa de bază, le prinzi pe toate.

Cea mai des întâlnită cauză este bucla cu <= în loc de <. Objects.checkIndex(i, n) verifică un indice și aruncă aceeași excepție, cu același mesaj.

Ce returnează

Excepția este aruncată de metoda care primește indicele greșit.

Exemple

Exemplul 1: Listă, tablou și text

import java.util.ArrayList;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        List<String> orase = new ArrayList<>(List.of("Iași", "Cluj", "Arad"));
        int[] note = {9, 10, 8};
        String cod = "RO";
        Runnable[] incercari = {
            () -> orase.get(3),
            () -> System.out.println(note[-1]),
            () -> cod.charAt(5),
        };
        for (Runnable r : incercari) {
            try {
                r.run();
            } catch (IndexOutOfBoundsException e) {
                System.out.println(e.getClass().getSimpleName() + ": " + e.getMessage());
            }
        }
    }
}

Rezultat

IndexOutOfBoundsException: Index 3 out of bounds for length 3
ArrayIndexOutOfBoundsException: Index -1 out of bounds for length 3
StringIndexOutOfBoundsException: Index 5 out of bounds for length 2

Exemplul 2: Bucla cu <= în loc de <

public class Main {
    public static void main(String[] args) {
        String[] elevi = {"Ana", "Mihai", "Ioana"};
        try {
            for (int i = 0; i <= elevi.length; i++) {
                System.out.println((i + 1) + ". " + elevi[i]);
            }
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("Eroare: " + e.getMessage());
        }
        System.out.println("Corect: for (int i = 0; i < elevi.length; i++) sau for (String e : elevi)");
    }
}

Rezultat

1. Ana
2. Mihai
3. Ioana
Eroare: Index 3 out of bounds for length 3
Corect: for (int i = 0; i < elevi.length; i++) sau for (String e : elevi)

Exemplul 3: Verificare înainte de acces

import java.util.List;
import java.util.Objects;

public class Main {
    static String locul(List<String> clasament, int loc) {
        int i = loc - 1;
        return i >= 0 && i < clasament.size() ? clasament.get(i) : "nimeni";
    }

    public static void main(String[] args) {
        List<String> clasament = List.of("Ioana", "Ana", "Radu");
        System.out.println("Locul 1: " + locul(clasament, 1));
        System.out.println("Locul 4: " + locul(clasament, 4));
        try {
            Objects.checkIndex(7, clasament.size());
        } catch (IndexOutOfBoundsException e) {
            System.out.println("checkIndex: " + e.getMessage());
        }
    }
}

Rezultat

Locul 1: Ioana
Locul 4: nimeni
checkIndex: Index 7 out of bounds for length 3

Greșeli frecvente

  • Scrii i <= lista.size() în condiția buclei. Ultimul indice valid este size() - 1; folosește < sau o buclă for-each.
  • Iei lista.get(0) fără să verifici dacă lista este goală.

Comenzi înrudite

  • Exception.printStackTrace: Afișează excepția și lista de apeluri (stack trace) care a dus la ea; implicit pe ieșirea de erori (System.err).
  • RuntimeException: Clasa de bază a excepțiilor neverificate: nu trebuie declarate cu throws și nici prinse obligatoriu.
  • List.get: get citește elementul de la o poziție; set îl înlocuiește și returnează valoarea veche.
  • String.charAt: Returnează caracterul (char) de la poziția dată; prima poziție este 0, ultima este length() – 1.