EMZETT.
Login

Break/Continue

In short: Two jump statements for controlling flow within loops: break leaves the loop completely, continue only skips the rest of the current iteration.

In more detail: break is also used in switch statements to prevent fallthrough between cases. In nested loops, both by default only affect the innermost loop — with named labels (outer: for (...) { ... break outer; }) this can be deliberately extended to an outer loop.

In Depth

outer:
for (int i = 0; i < 3; i++) {
    for (int j = 0; j < 3; j++) {
        if (j == 1) continue;        // skips the rest ONLY of the inner loop
        if (i == 2) break outer;     // leaves BOTH loops completely
        System.out.println(i + "," + j);
    }
}

Without a label, break and continue always only affect the immediately enclosing loop — a common logic error in deeply nested loops, when you actually wanted to leave the outer loop. Labels (name: directly before the loop) solve this explicitly, but are rarely used in practice, because nested loops with labels are often a sign that the logic would be better extracted into its own method with return — a return within a method immediately leaves the entire method, including all enclosing loops, with no label needed at all.

break in switch statements

Besides loops, break is also central to classic switch statements (not the newer switch expression with ->), to prevent so-called fallthrough:

int day = 3;
switch (day) {
    case 1:
        System.out.println("Monday");
        break; // without break, execution would "fall through" into case 2
    case 2:
        System.out.println("Tuesday");
        break;
    case 3:
        System.out.println("Wednesday");
        break;
    default:
        System.out.println("Unknown");
}

If you forget break in a case, execution simply continues into the next case block (“fallthrough”) — a classic, hard-to-find beginner mistake that modern switch expressions (case 1 ->) since Java 14 avoid entirely, since they no longer have implicit fallthrough.

continue in practice

continue is often used to skip “uninteresting” cases early and avoid additionally indenting the loop’s main code (a so-called “guard clause”):

for (String word : words) {
    if (word.isEmpty()) continue; // simply ignore empty entries
    if (word.startsWith("#")) continue; // skip comments
    process(word); // main logic stays clear, without deep if nesting
}

Comparison to return

return and break are sometimes confused by beginners: break only leaves the loop/the switch, the code after it in the method continues running normally. return immediately leaves the ENTIRE method, no matter how many loops are still open.

Common pitfall: continue in for-each loops

In a for-each loop (for (String s : list)), continue works just like in a classic for loop, BUT: modifications to the iteration variable s itself (e.g. s = "different") have no effect whatsoever on the original list, since s is only a local copy of the reference for the current iteration. Anyone who tries to remove elements from a list during a for-each iteration instead gets a ConcurrentModificationException — that requires an explicit iterator with iterator.remove().

Deliberately ending infinite loops with break

A common pattern is a deliberate infinite loop that’s only left via a break condition inside it — useful when the exit condition has to be checked in the middle of the loop body, not at the start:

while (true) {
    String input = scanner.nextLine();
    if (input.equals("exit")) break;
    process(input);
}

This is often more readable than a complicated condition directly in the while header, especially when the exit condition is only known after an action (here: reading input) has happened.

See also: Loops, Switch Statement