Was bewirken die Anweisungen break und continue? Was ist mit goto?

Die beiden Anweisungen break und continue dienen zur erweiterten Steuerung von Schleifen und, im Falle von break, auch derjenigen von switch-Anweisungen.

break

Wird die Anweisung break innerhalb einer Schleife notiert, so bewirkt sie, dass deren Ausführung an dieser Stelle beendet und die Programmausführung sofort nach der Schleife fortgesetzt wird. Das folgende Beispiel demonstriert dies.

public class BreakBsp {
    public static void main(String[] args) {
        for (int i = 0; i < 5; i++) {
            System.out.println(i);
            if (i == 3) {
                break;
            }
        }
        System.out.println("nach Schleife");
    }
}

Ohne die bedingte Anweisung würde die Zählvariable in obigem Beispiel von 0 bis 4 hochgezählt und ausgegeben werden. Die Anweisung bewirkt hier jedoch das Verlassen der Schleife, sobald i den Wert 3 erreicht hat. Die Ausgabe des Programms sieht demnach wie folgt aus:

0
1
2
3
nach Schleife

Liegen geschachtelte Schleifen vor, so bezieht sich die Anweisung nur auf diejenige, in der die Anweisung auch notiert wurde.

public class BreakBsp {
    public static void main(String[] args) {
        for (int n = 0; n < 5; n++) {
            for (int i = 0; i < 5; i++) {
                System.out.println(n + " " + i);
                if (i == 3) {
                    break;
                }
            }
            System.out.println("nach innerer Schleife");
        }
        System.out.println("nach beiden Schleifen");
    }
}

Die Ausgabe:

0 0
0 1
0 2
0 3
nach innerer Schleife
1 0
1 1
1 2
1 3
nach innerer Schleife
2 0
2 1
2 2
2 3
nach innerer Schleife
3 0
3 1
3 2
3 3
nach innerer Schleife
4 0
4 1
4 2
4 3
nach innerer Schleife
nach beiden Schleifen

Die äußere Schleife wird hier fünfmal durchlaufen, die innere jedes Mal jedoch nur, solange deren Zählvariable kleiner 4 ist.

Die break-Anweisung wird auch in switch-case-Verzweigungen verwendet, um bei Zutreffen eines case-Falls die Verzweigung zu verlassen. Siehe hierzu den Artikel zur switch-case-Verzweigung.

continue

Die Anweisung continue bewirkt im Gegensatz zum break, dass lediglich der aktuelle Schleifendurchlauf (und nicht die vollständige Schleife!) an der Stelle der Anweisung verlassen und der Programmablauf dann mit dem nächsten Schleifendurchlauf fortgesetzt wird.

for (int i = 0; i < 5; i++) {
    System.out.println(i);
    if (i == 3) {
        continue;
    }
    System.out.println("nach continue");
}
System.out.println("nach Schleife");

Die Ausgabe sieht wie folgt aus:

0
nach continue
1
nach continue
2
nach continue
3
4
nach continue
nach Schleife

Man erkennt hier, dass die Ausgabe 'nach continue' durch den Abbruch beim Durchlauf mit der Zählvariablen 3 nicht erfolgt.
Bei der Verwendung von geschachtelten Schleifen verhält es sich bei continue analog zum break: Die Anweisung bezieht sich nur auf die notierende Schleife, übergeordnete bleiben unberücksichtigt.

labeled break und labeled continue

Wenn sich der Abbruch eines Schleifendurchlaufs auf eine andere Iterationsebene beziehen soll, können Markierungen, labeled break und labeled continue, verwendet werden. Hierzu muss ein beliebiger Bezeichner gefolgt von einem Doppelpunkt vor die zu beeinflussende Struktur als Markierung gesetzt werden. Die Sprunganweisung selbst erfolgt dann durch break oder continue gefolgt vom Bezeichner der Markierung ohne Doppelpunkt.

public class Label {
    public static void main(String[] args) {
        aussen:
        for(int i=0; i < 4; i++) {
            for(int j=0; j < 4; j++) {
                System.out.println(i + " " + j);
                if(j==2) {
                    break aussen;
                }
            }
        }
    }
}

Der obige Quelltext erzeugt die folgende Ausgabe

0 0
0 1
0 2

Die bedingte Sprunganweisung erfolgt in der inneren Schleife, wenn deren Zählvariable den Wert 2 annimmt. Dadurch, dass die Markierung den Kopf der äußeren Schleife kennzeichnet, wird nicht nur die innere Schleife, sondern auch die äußere abgebrochen.
Wird das break durch ein continue ersetzt, so wird die äußere Schleife wieder durchlaufen, jedoch immer nur bis der Zähler der inneren Schleife 2 beträgt. Die Ausgabe gestaltet sich dann wie folgt:

0 0
0 1
0 2
1 0
1 1
1 2
2 0
2 1
2 2
3 0
3 1
3 2

Das jeweilige break- oder continue-statement bezieht sich also nicht nur auf die Schleife, in deren Verlauf es notiert wurde, sondern auf die übergeordnete, markierte Struktur, vor der es notiert wurde.
Noch deutlicher wird dies, wenn man noch eine dritte, äußere Schleife hinzufügt:

public class Label {
    public static void main(String[] args) {
    for (int n = 0; n < 4; n++) {
            aussen:
            for (int i = 0; i < 4; i++) {
                for (int j = 0; j < 4; j++) {
                    System.out.println(n + " " + i + " " + j);
                    if (j == 2) {
                        break aussen;
                    }
                }
            }
        }
    }
}

Die Ausgabe:

0 0 0
0 0 1
0 0 2
1 0 0
1 0 1
1 0 2
2 0 0
2 0 1
2 0 2
3 0 0
3 0 1
3 0 2

Hier ist zu erkennen, dass die nun mittlere Schleife, vor der die Sprungmarke notiert wurde, bereits bei ihrem ersten Durchlauf unterbrochen wird (die Werte der mittleren Spalte bleiben bei 0), nachdem die Zählvariable der inneren Schleife den Wert 2 angenommen hat. Die äußere Schleife läuft jedoch weiter (die erste Spalte zeigt alle Werte von 0 bis 3).

Der Vollständigkeit halber sei erwähnt, dass Markierungen auch außerhalb von Schleifen vor Blöcken notiert werden können. Um unschönen Spaghetti-Code zu vermeiden, sollte hierauf jedoch verzichtet werden.

goto

Um häufigen Nachfragen zu begegnen, ein kurzes Wort zu goto. Die, historisch gesehen, aus den maschinennahen Assembler-Sprachen stammende goto-Anweisung ist bis heute zwar Bestandteil auch vieler höherer Programmiersprachen, ihre Verwendung gilt jedoch als ausgesprochen problematisch.1,2
Hier ist der Grund zu suchen, weshalb in Java auf die Implementierung des zwar reservierten, gleichwohl jedoch funktionslosen Schlüsselwortes verzichtet wurde.

Quellen
  1. Edsger W. Dijkstra: Letters to the editor: Go To Statement Considered Harmful. In: Communications of the ACM. Band 11, Nr. 3, März 1968, S. 147–148
  2. David R. Tribble: Go To Statement Considered Harmful: A Retrospective.

Wenn Ihnen javabeginners.de gefällt, freue ich mich über eine Spende an diese gemeinnützigen Organisationen.