Control flow and the modern switch
Use if, else if and else for conditions, and switch when one value chooses between many branches.
The classic switch "falls through" to the next case unless you write break, which is a very common bug. Java 14 made switch expressions final: arrow labels (case X ->) never fall through, several labels can share one arm, and the whole switch can return a value. Use yield to return a value from a block arm.
Java 21 went further with pattern matching in switch, covered in the Modern Java module.
if, else if and else
Conditions must be boolean expressions. Always use braces, even for one line; it prevents bugs when someone adds a second line later.
if (marks >= 90) {
grade = "A";
} else if (marks >= 75) {
grade = "B";
} else {
grade = "C";
}The classic switch statement
Classic switch works on integers, char, String (Java 7) and enums. Without break, execution falls through into the next case, which is a common bug.
switch (day) {
case "SAT":
case "SUN":
System.out.println("Weekend");
break;
default:
System.out.println("Weekday");
}Switch expressions (Java 14)
Arrow labels don't fall through, a switch can return a value, and the compiler checks that enum switches cover every case. Use yield to return a value from a block.
int days = switch (month) {
case FEB -> leapYear ? 29 : 28;
case APR, JUN, SEP, NOV -> 30;
default -> 31;
};
String label = switch (status) {
case PAID -> "Paid";
case FAILED -> {
log.warn("Payment failed");
yield "Failed";
}
default -> "Pending";
};for, while and do-while
for: when you know how many times to repeat.while: repeat while a condition holds; it may run zero times.do โฆ while: runs at least once, and checks the condition afterwards (handy for input prompts).
for (int i = 1; i <= 5; i++) System.out.print(i + " ");
int n = 100;
while (n > 1) n /= 2;
int choice;
do {
choice = askUser();
} while (choice < 1 || choice > 3);The enhanced for loop (for-each)
For-each reads every element of an array or collection without an index. You can't change the collection's size inside it: removing items throws ConcurrentModificationException; use removeIf or an iterator instead.
for (String name : names) {
System.out.println(name);
}
names.removeIf(n -> n.isBlank()); // safe removalbreak, continue and labels
break leaves the loop, and continue skips to the next iteration. A label lets break leave an outer loop from inside a nested one.
outer:
for (int[] row : grid) {
for (int cell : row) {
if (cell < 0) continue; // skip negatives
if (cell == target) break outer; // stop both loops
}
}Pattern matching in switch (Java 21)
Modern switches can test types and destructure records, with guards written using when. The patterns lesson covers this in depth.
String describe(Object o) {
return switch (o) {
case Integer i when i > 100 -> "big number";
case Integer i -> "number " + i;
case String s -> "text of length " + s.length();
case null -> "nothing";
default -> "something else";
};
}Old way vs new way
String type;
switch (day) {
case SAT:
case SUN:
type = "Weekend";
break; // forget this and you fall through
default:
type = "Weekday";
}enum Day { MON, TUE, WED, THU, FRI, SAT, SUN }
String type = switch (day) {
case SAT, SUN -> "Weekend";
case FRI -> {
log("Almost there");
yield "Weekday";
}
default -> "Weekday";
};Common mistake
Mixing arrow labels and colon labels in one switch. That's a compile error, so pick one style.
Under the hood
The compiler checks switch expressions for exhaustiveness. Over an enum with every constant covered, no default is needed, and adding a new constant later becomes a compile error instead of a silent bug. Strings in switch (Java 7) compile to a switch on hashCode() followed by an equals() check.
Check yourself
Which is true for case X -> arms?
How this connects
Know these first
Part of Java from zero, Upgrade from Java 8 to Java 25.
Was this lesson helpful?
Finished reading? Mark it complete to track your progress.