For-Schleife
Bild: Bagok, Public domain, Wikimedia Commons
Kurz: Eine kopfgesteuerte Schleife mit fest definiertem Zähler — Startwert, Abbruchbedingung und Schrittweite stehen alle im Schleifenkopf.
Genauer: Klassische Syntax: for (int i = 0; i < n; i++) { ... }. Java kennt zusätzlich die For-Each-Variante (for (Type element : collection) { ... }), die über Arrays oder Collections iteriert, ohne einen manuellen Index zu führen — praktisch, aber ohne direkten Zugriff auf den Index selbst.
for (int i = 0; i < 5; i++) {
System.out.println(i);
}Im Detail
Aufbau des Schleifenkopfs
int[] zahlen = {10, 20, 30, 40};
// Klassische For-Schleife: Zugriff auf den Index selbst möglich
for (int i = 0; i < zahlen.length; i++) {
System.out.println("Index " + i + ": " + zahlen[i]);
}
// For-Each-Variante: kürzer, aber kein Zugriff auf den Index
for (int zahl : zahlen) {
System.out.println(zahl);
}Der Schleifenkopf der klassischen for-Schleife besteht aus drei durch Semikolon getrennten Teilen: Initialisierung (läuft genau einmal, vor dem ersten Durchlauf), Bedingung (wird vor JEDEM Durchlauf geprüft, bricht die Schleife ab sobald sie false liefert) und Inkrement/Update (läuft nach jedem Durchlauf-Körper, vor der nächsten Bedingungsprüfung). Alle drei Teile sind optional — for (;;) { ... } ist eine gültige, bewusst endlose Schleife (äquivalent zu while (true)), die man z. B. in einem Server-Loop mit einem break an der richtigen Stelle beendet. Mehrere Variablen lassen sich mit Komma gleichzeitig initialisieren/inkrementieren: for (int i = 0, j = 10; i < j; i++, j--) — beide laufen synchron in entgegengesetzte Richtungen, praktisch etwa um ein Array gleichzeitig von beiden Enden zu durchlaufen (z. B. beim Palindrom-Check).
For-Each als syntaktischer Zucker
Die For-Each-Variante (for (Type element : collection)) ist syntaktischer Zucker über einem Iterator — der Compiler übersetzt sie intern in etwas wie Iterator<T> it = collection.iterator(); while (it.hasNext()) { T element = it.next(); ... }. Sie eignet sich, wann immer man einfach nur JEDES Element besuchen will, ohne den Index selbst zu brauchen, und funktioniert mit Arrays und allem, was das Iterable-Interface implementiert (also praktisch allen Collections wie ArrayList, HashSet, LinkedList). Ein wichtiger Unterschied zur indexbasierten Schleife: Elemente während einer laufenden For-Each-Schleife direkt aus der Collection zu entfernen wirft eine ConcurrentModificationException, weil der intern verwendete Iterator merkt, dass sich die Struktur “unter ihm” verändert hat — dafür braucht es stattdessen iterator.remove() über einen expliziten Iterator, oder man baut sich eine separate Liste der zu entfernenden Elemente und löscht die erst nach der Schleife.
Typische Fallstricke
Ein klassischer Anfängerfehler ist das sogenannte Off-by-one-Problem: i <= zahlen.length statt i < zahlen.length führt zu einer ArrayIndexOutOfBoundsException, weil Array-Indizes bei Java bei 0 beginnen und der letzte gültige Index length - 1 ist. Ein weiterer häufiger Fehler ist das versehentliche “Schatten”-Deklarieren derselben Zählervariable in verschachtelten Schleifen (for (int i = ...) { for (int i = ...) }) — das kompiliert nicht, weil i im inneren Scope schon existiert, was Java-Compiler zum Glück sofort mit einer klaren Fehlermeldung quittieren. Vorsicht ist auch bei Fließkomma-Zählern geboten: for (double d = 0.0; d != 1.0; d += 0.1) kann durch Rundungsfehler bei Gleitkommazahlen theoretisch nie terminieren, weil d die exakte 1.0 möglicherweise nie trifft — hier sollte man entweder mit < statt != vergleichen oder einen ganzzahligen Zähler verwenden und erst im Schleifenkörper umrechnen.
Abgrenzung zu verwandten Schleifentypen
Im Gegensatz zur While-Schleife, die primär für Bedingungen ohne festen Zähler gedacht ist (z. B. “solange Benutzereingabe nicht ‘exit’ ist”), ist die for-Schleife die natürliche Wahl, wenn die Anzahl der Durchläufe von vornherein bekannt oder berechenbar ist — etwa “genau n-mal” oder “einmal pro Element einer Liste”. Alle drei Grundformen (klassisch, For-Each, sowie die seltener genutzte Kombination mit Break/Continue zum vorzeitigen Verlassen oder Überspringen einzelner Durchläufe) lassen sich ineinander überführen, unterscheiden sich aber deutlich in Lesbarkeit: For-Each ist meist die kürzeste und am wenigsten fehleranfällige Form, sobald der Index selbst nicht gebraucht wird.
Siehe auch: Schleifen, While-Schleife, Index, Arrays, Break/Continue