For-Each-Form der For-Schleife

Wie funktioniert die ForEach-Form der For-Schleife prinzipiell?

Mit dieser Form der Schleife kann man über Arrays und über Subtypen des Interfaces Iterable (typischerweise sind das Collections) iterieren, ohne explizit eine Indexvariable oder einen Iterator anzugeben. Man gibt stattdessen Namen und Typ einer lokalen Variablen an, in die dann automatisch bei jedem Schleifendurchlauf der jeweils nächste Wert des Arrays bzw. des Iterable kopiert wird. Codebeispiel:

import java.util.LinkedList;

public class Test {
    public static void main(String[] args) {

        // Array-Initialisierung mit "klassischer" For-Schleife
        String[] array = new String[3];
        for (int i = 0; i < array.length; i++) {
            array[i] = "Wert";
        }
       
        // Iteration über den Array mit ForEach-Schleife
        for (String element : array) {
            System.out.println(element);
        }
       
        System.out.println();
       
        // Initialisierung einer LinkedList mit den Elementen
        // des Arrays mit Hilfe einer ForEach-Schleife
        LinkedList <String> list = new LinkedList <String>();
        for (String element : array) {
            list.add(element);
        }

        // Iteration über die LinkedList mit ForEach-Schleife
        for (String element : list) {
            System.out.println(element);
        }
       
        System.out.println();

        // Aber Achtung: Eine *Zuweisung* an die lokale
        // Iterationsvariable bleibt wirkungslos!
        for (String element : array) {
            element = "Neuer Wert";
        }

        // Wie man sieht: Die Werte im Array sind unverändert
        for (String element : array) {
            System.out.println(element);
        }
    }
}

Kann ich in einer ForEach-Schleife keine Zuweisung an das aktuelle Element vornehmen?

Nein, das geht nicht. Die Variable, in welche die Elemente der Iteration kopiert werden, verhält sich hier ähnlich dem Parameter eines Methodenaufrufs: Es wird jeweils der Wert des „Originals“ (von außerhalb des Schleifenrumpfs) hineinkopiert (Siehe dazu auch den Abschnitt „Call by Value / Call by Reference“). Eine Zuweisung an die lokale Variable verändert also nicht das Iterable, über das iteriert wird. Wenn der Wert eine Objektreferenz ist, kann aber selbstverständlich über die lokale Kopie der Referenz das referenzierte Objekt (durch Methodenaufruf oder Attributzuweisung) verändert werden.

Warum bekomme ich eine ArrayIndexOutOfBoundsException beim Iterieren über einen Array?

Hier der problematische Quellcode:

    for (int i : myArray) {
        System.out.println(myArray[i]);
    }

Antwort:    Die ForEach-Form der For-Schleife arbeitet nicht mit sichtbaren Indexzahlen. Die lokale Variable enthält also nicht, wie bei der klassischen Form, die Indexzahlen der Elemen-te, sondern vielmehr (eins nach dem anderen) die Werte der Elemente selbst. Offenbar ist eines dieser Elemente in deinem Beispiel größer als der größte erlaubte Index des Arrays. Richtig wäre also (ich nenne die temporäre Variable hier bewusst nicht i, sondern elem, um anzudeuten, dass es sich nicht um eine Indexzahl handelt):

    for (int elem : myArray) {
        System.out.println(elem);
    }