🔀 Control Flow · Beginner

Dangling else & braces in Java

else binds to the nearest if; why braces prevent bugs.

🧩 The mysteryTwo lines are indented under an if. The condition is false. One of the lines runs anyway. Is Java ignoring your indentation? Yes. Completely.

One statement, no more

Without braces, an if controls exactly one statement. Indentation is only for humans: the compiler ignores whitespace. So the second println below is *not* part of the if, it always runs.

if (x > 5)
    System.out.println("big");
    System.out.println("done");
🔮 Predict it

Your turn

coins is 3. What prints?

int coins = 3;
if (coins > 10)
    System.out.println("Rich!");
    System.out.println("Shop opened");
  1. Nothing is printed
  2. Rich! Shop opened
  3. Shop opened
Show the answer

Only Shop opened. The if (false) guards just the first println. The second one *looks* guarded thanks to its indentation, but it always runs.

The dangling else

With nested ifs and no braces, an else pairs with the nearest preceding if that doesn't already have an else, whatever the indentation says. The inner if/else then becomes the single body of the outer if: if the outer condition is false, neither branch runs.

if (a > 0)
    if (b > 0)
        System.out.println("both");
else // belongs to if (b > 0)!
    System.out.println("a not positive");
🔮 Predict it

Who owns this else?

age is 20, member is false. What prints?

int age = 20;
boolean member = false;
if (age >= 18)
    if (member)
        System.out.println("VIP");
else
    System.out.println("Too young");
  1. Nothing is printed
  2. VIP
  3. Too young
Show the answer

Too young, which is a lie! The else belongs to the inner if (member). Age 20 passes the outer check, member is false, so the inner else runs. Had age been 15, *nothing* would print.

⚠️ The trap

The stray semicolon

A ; right after if (...) is an empty statement: it becomes the entire body of the if. The block below is just an ordinary block that always runs. This prints "In stock" even when stock is 0.

int stock = 0;
if (stock > 0);
{
    System.out.println("In stock");
}

Braces every time

✗ Ambiguous
if (a > 0)
    if (b > 0)
        System.out.println("both");
else
    System.out.println("no a");

The else silently attaches to the inner if.

✓ Crystal clear
if (a > 0) {
    if (b > 0) {
        System.out.println("both");
    }
} else {
    System.out.println("no a");
}

With braces, the structure you mean is the structure you get.

💼 In the real world

In real projects

In 2014 Apple shipped the "goto fail" bug: a duplicated line under a brace-less if in its TLS code always ran, skipping a crucial certificate check on iOS and macOS. That's why most style guides, including Google's Java Style Guide, require braces even for one-line bodies.

Key takeaways

  1. else binds to the closest unmatched if, whatever the indentation
  2. Without braces, an if controls exactly ONE statement
  3. A stray ; after if (...) is an empty statement, so the block always runs
  4. Always use braces, even for one-line bodies

💡 Braces are like putting things in labelled boxes: without them, the compiler decides what goes where, not your indentation.

🤯 Did you know?

Python made indentation part of the language itself, so code can never look one way and run another. Java chose braces instead, which is why tools like formatters and linters matter so much.

Practice questions

What does this print?

int x = 0;
if (x > 5)
    System.out.println("big");
    System.out.println("done");
  1. Nothing is printed
  2. big done
  3. done
Check your answer

done. Without braces, only the first statement belongs to the if. The second println is indented, but it always runs.

What does this print?

int a = 1, b = -1;
if (a > 0)
    if (b > 0)
        System.out.println("both");
else
    System.out.println("a not positive");
  1. both
  2. a not positive
  3. Nothing is printed
Check your answer

a not positive. The else belongs to the inner if (b > 0), not to the outer one. a > 0 is true and b > 0 is false, so the else runs and prints a misleading message.

Next: switch, where forgetting one tiny word makes your code run cases you never chose.