Module 3 · Control Flow & Program Structure ⏱ 19 min

break/continue and Labeled Loops

By the end of this lesson you will be able to:
  • Use break to exit a loop early and continue to skip an iteration, and predict where control goes next
  • Explain why break and continue affect only the nearest enclosing loop in a nested structure
  • Use a label to make break or continue target an outer loop

Most loops you have written so far run from start to finish, touching every element. That is fine for adding up a list, but real programs constantly need to stop early or skip ahead. A login form scans a list of users and should stop the instant it finds a match — there is no point checking the rest. A report loop should jump past weekends when totalling daily sales. Telling a loop to leave early, or to step past an item, is the difference between code that does exactly enough work and code that wastes time.

Java gives you two keywords for this: break exits the loop entirely, and continue abandons the current iteration and moves to the next one. Both look tiny, but they change the path a program takes — so predicting their effect is a core reading skill.

flowchart TD
  N["start of an iteration"] --> C{"should we<br/>break or continue?"}
  C -->|"break"| X["leave the loop<br/>immediately"]
  C -->|"continue"| S["skip the rest<br/>go to next item"]
  C -->|"neither"| R["run the rest<br/>of the body"]
  R --> S
  style X fill:#b45309,color:#fff
  style S fill:#166534,color:#fff
break leaves the loop; continue skips the rest of this iteration and moves to the next one.

break: leave the loop now

When Java reaches break, it immediately exits the nearest enclosing loop — no more iterations, no more body, no condition check. Control jumps to the statement right after the loop. The classic use is a search that stops on the first hit: you do not need a boolean flag, because break already says stop.

for (int n : nums) {
    if (n == target) {
        System.out.println("found");
        break;
    }
}

Whatever comes after the loop runs next, exactly once. Note what break does not do: it does not return a value, and it does not unwind more than one loop. In a nested structure, break only escapes the innermost loop it sits inside — a detail that quietly becomes a bug, as you will see below.

Main.java — a find-first search that stops with break. Real, compiling Java.
public class Main {
    public static void main(String[] args) {
        int[] nums = {4, 8, 15, 16, 23};
        int target = 15;
        int index = -1;
        for (int i = 0; i < nums.length; i++) {
            if (nums[i] == target) {
                index = i;
                break;
            }
        }
        System.out.println("found at index " + index);
    }
}

continue: skip this one, go to the next

continue is the gentler sibling. It abandons the rest of the current iteration and jumps straight to the next one — the loop itself keeps going. Reach for it when most of the body should run, but some items need to be passed over.

There is a subtlety about where continue jumps, and it depends on the loop type. In a for loop, continue jumps to the update step (the i++ part), so the counter still advances and the loop progresses. In a while loop there is no hidden update, so continue jumps straight to the condition — and if you have not already advanced your counter on the line above, the loop runs forever. This is why continue feels safe inside for loops and dangerous inside while loops.

Main.java — continue skips the even numbers so only the odds are summed. Real, compiling Java.
public class Main {
    public static void main(String[] args) {
        int total = 0;
        for (int i = 1; i <= 5; i++) {
            if (i % 2 == 0) {
                continue;
            }
            total = total + i;
        }
        System.out.println("sum of odds: " + total);
    }
}
flowchart TD
  subgraph OUTER["outer loop"]
    subgraph INNER["inner loop"]
      I["iteration"] --> T{"break?"}
      T -->|"yes"| B["break exits<br/>inner loop only"]
      T -->|"no"| W["run the body"]
      W --> I
    end
    B --> NXT["outer loop<br/>moves to next i"]
  end
  style B fill:#b45309,color:#fff
In a nested loop, break only exits the inner loop; the outer loop continues untouched.

The classic trap: break only leaves the nearest loop

Drop a break inside a loop that is itself inside another loop, and the break exits only the inner loop. The outer loop is completely unaffected — it happily moves to its next iteration and starts the inner loop over again. This is the single most common surprise with break, and it is not a bug in Java; it is the rule.

If you actually need to leave both loops at once — say you are searching a grid and found your cell — an ordinary break will not do it. The inner loop ends, the outer loop continues, and your search re-scans the next row. Recognising this gap is what leads to the next idea: labels.

flowchart TD
  L["label<br/>outer"] --> O["outer loop"]
  O --> I["inner loop"]
  I --> D{"break outer?"}
  D -->|"yes"| OUT["leave both loops"]
  D -->|"no"| M["keep searching"]
  M --> I
  style L fill:#3776ab,color:#fff
  style OUT fill:#b45309,color:#fff
A label lets break or continue target a chosen loop, escaping every loop nested inside it.

Labels: break out of a chosen loop

When you need a break or continue to reach past the nearest loop, Java lets you name a loop with a label and aim at it. A label is an identifier followed by a colon, placed just before the loop.

outer:
for (int r = 0; r < rows; r++) {
    for (int c = 0; c < cols; c++) {
        if (grid[r][c] == target) {
            break outer;   // leaves BOTH loops
        }
    }
}

break outer exits the loop named outer, no matter how many loops are nested inside it. continue outer works the same way: it skips to the next iteration of the labelled loop, jumping over every inner loop in between. Labels are rare in everyday Java because most code is better restructured into a method that simply returns — but when you do need them, nothing else expresses the intent as clearly.

Use them sparingly

Both keywords are tools, not habits. A loop with a break buried in the middle is harder to reason about than one whose stopping rule sits at the top, because the real exit condition is now scattered across the body. The same is true of continue: stack two or three in one loop, and a reader can no longer see the happy path through the guards.

Reach for break when a search has clearly finished, and for continue when a guard at the top of the body saves a whole level of indentation. If you are chaining four continue statements, invert the condition or extract the body into its own method. Readability is a feature, not a nicety.

Exercise

break stops the sum early. Predict the exact output (two lines) — the loop abandons its work the moment it hits 9.

public class Main {
    public static void main(String[] args) {
        int[] nums = {3, 7, 2, 9, 4};
        int sum = 0;
        for (int n : nums) {
            if (n == 9) {
                break;
            }
            sum = sum + n;
        }
        System.out.println(sum);
        System.out.println(nums[0]);
    }
}
Exercise

continue skips the evens. Predict the exact output (two lines) — odd numbers are added, even ones are passed over.

public class Main {
    public static void main(String[] args) {
        int sum = 0;
        int count = 0;
        for (int i = 1; i <= 6; i++) {
            if (i % 2 == 0) {
                continue;
            }
            sum = sum + i;
            count = count + 1;
        }
        System.out.println(sum);
        System.out.println(count);
    }
}
Exercise

Inside a for loop, what happens immediately after continue runs?

Exercise

The nested-loop trap. A break sits inside an inner loop. Predict the exact output (three lines) — remember which loop the break actually leaves.

public class Main {
    public static void main(String[] args) {
        for (int i = 1; i <= 3; i++) {
            for (int j = 1; j <= 3; j++) {
                if (j == 2) {
                    break;
                }
                System.out.println(i + "," + j);
            }
        }
    }
}
Exercise

Labelled break transfer. The inner loop hunts for a 0 and then breaks the OUTER loop by name. Predict the exact output (two lines).

public class Main {
    public static void main(String[] args) {
        int[][] grid = {
            {1, 2, 3},
            {4, 5, 6},
            {7, 8, 0}
        };
        int foundRow = -1;
        int foundCol = -1;
    outer:
        for (int r = 0; r < grid.length; r++) {
            for (int c = 0; c < grid[r].length; c++) {
                if (grid[r][c] == 0) {
                    foundRow = r;
                    foundCol = c;
                    break outer;
                }
            }
        }
        System.out.println(foundRow);
        System.out.println(foundCol);
    }
}

Recap

  • break exits the nearest enclosing loop immediately; the statement after the loop runs next.
  • continue skips the rest of the current iteration and moves to the next one. In a for loop it still runs the update step; in a while loop it jumps to the condition.
  • In nested loops, break and continue affect only the innermost loop unless you label an outer one.
  • A label (name:) before a loop lets break outer and continue outer target a specific loop, escaping every loop nested inside it.

Next you will put these flow keywords to work on arrays — Java's fixed-length, indexed collections — where stopping early and skipping ahead become genuinely useful.

Checkpoint quiz

What is the difference between break and continue?

In outer: for(...) { for(...) { break outer; } }, which loops does break outer exit?

Go deeper — technical resources