Java · Beginner
Conditions in Java: if, else and switch
In short: An if statement runs its block only when a boolean condition is true; else if and else add alternatives tested in order, and exactly one branch of the chain runs. switch compares one value against fixed cases and, since Java 14, can be written as an expression with arrows and no fall-through.
Choosing a path
Programs react to their data: a ticket costs one price for a child and another for an adult, a booking is refused when a weekly limit is reached, a command is handled differently depending on which word the user typed. The if statement makes a block conditional. Java evaluates the expression in the parentheses, runs the block when it is true and skips it when it is false.
The condition must be a boolean. Unlike languages with "truthy" values, Java does not accept a number or a string here: if (count) with an int fails to compile with int cannot be converted to boolean. Write if (count > 0) or if (!name.isEmpty()) instead. This strictness catches a whole family of slips, including if (x = 5), which does not compile because the assignment produces an int.
else attaches a block that runs when the condition was false. else if tests a further condition only when everything above it failed. The whole chain is one statement: Java tests from the top, runs the first block whose condition holds and ignores the rest, even if a later condition would also have been true. Order therefore matters. Put the most specific test first, or make each condition self-contained. A chain differs from a series of separate if statements, each of which is tested regardless of the others.
Braces are optional when a branch is a single statement, but leaving them out is a well-known trap: a second statement added later sits outside the if and always runs. Use braces every time.
switch compares one value against a list of constants. The original form uses case X: labels with break after each block; forgetting a break lets execution fall through into the next case, which is sometimes intended and often a bug. Since Java 14 the arrow form case X -> ... runs exactly one case with no fall-through, several constants can share one case separated by commas, and the whole switch can be an expression that yields a value. A switch expression must cover every possible input, so for strings and numbers it needs a default.
Comparing text needs care. == on two String variables asks whether they are the same object, not whether they contain the same characters. Two literals in the source may share one object, so == sometimes appears to work, then fails on text that came from input. Always use equals, or equalsIgnoreCase when case should not matter.
When the choice is between two values rather than two blocks, the conditional operator condition ? a : b from the operators lesson is shorter and can sit inside an expression.
Syntax
if (condition) {
// runs when condition is true
} else if (otherCondition) {
// tested only when the first was false
} else {
// runs when nothing above matched
}
String label = switch (value) { // switch expression, Java 14+
case 1, 2 -> "low";
case 3 -> "medium";
default -> "high";
};
switch (value) { // switch statement with arrows
case 1 -> System.out.println("one");
default -> System.out.println("other");
}A case body that needs several statements goes in braces after the arrow: case 1 -> { ...; }. In a switch expression such a block returns its value with yield.
Ticket prices with an if-else chain
A museum charges by age, with a weekend surcharge. The program is run with the input lines 70 and true.
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int age = in.nextInt();
boolean weekend = in.nextBoolean();
int price;
if (age < 4) {
price = 0;
} else if (age < 16) {
price = 6;
} else if (age >= 65) {
price = 7;
} else {
price = 11;
}
if (weekend && price > 0) {
price += 2;
}
System.out.println("Age " + age + ", weekend: " + weekend);
System.out.println("Ticket: " + price);
}
}Input given to the program: 70 ↵ true
Output
Age 70, weekend: true Ticket: 9
70 fails the first two tests and passes the third, so price becomes 7 and the else is skipped. The second branch can say age < 16 without also checking age >= 4, because reaching it already means the first test failed. The separate if afterwards is independent of the chain and adds the surcharge; && keeps free tickets free. Declaring price without a value is fine because every branch assigns it, which the compiler verifies.
switch with arrows
Opening hours by day name, then a numbered hall. The program is run with the input Sunday.
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String day = in.nextLine();
String opening = switch (day) {
case "Saturday", "Sunday" -> "10:00";
case "Monday" -> "closed";
default -> "08:30";
};
System.out.println(day + ": " + opening);
int hall = 2;
switch (hall) {
case 1 -> System.out.println("pool");
case 2 -> System.out.println("gym");
default -> System.out.println("unknown hall");
}
}
}Input given to the program: Sunday
Output
Sunday: 10:00 gym
The first switch is an expression: it produces a String that is assigned to opening, and the semicolon after the closing brace ends that assignment. Two day names share one case. Because it is an expression it must handle every possible String, hence default. The second switch is a statement; each arrow runs exactly one branch and nothing falls through into the next.
Comparing strings and nesting conditions
A gym's class booking rule: premium members book freely, basic members get three classes a week. The program is run with the input lines basic and 2.
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String plan = in.nextLine();
int booked = in.nextInt();
if (plan.equals("premium")) {
System.out.println("Booking confirmed");
} else if (plan.equals("basic")) {
if (booked < 3) {
System.out.println("Booking confirmed");
if (booked == 2) {
System.out.println("That was your last free class this week");
}
} else {
System.out.println("Weekly limit reached");
}
} else {
System.out.println("Unknown plan: " + plan);
}
String status = booked == 0 ? "first class" : "returning";
System.out.println(status);
}
}Input given to the program: basic ↵ 2
Output
Booking confirmed That was your last free class this week returning
plan.equals("basic") compares the characters, which is what we mean; plan == "basic" would be false here because the text came from input and is a different object from the literal. The nested if blocks run only inside the basic branch, and the innermost one only when this booking used the last free slot. Two levels of nesting read fine; beyond that, combine conditions with && or move the logic into a method.
Classic switch versus arrow switch
| Aspect | `case X:` with break | `case X ->` (Java 14+) |
|---|---|---|
| Fall-through | yes, unless each case ends with break | never |
| Several constants per case | stack labels: case 1: case 2: | case 1, 2 -> |
| Usable as an expression | no | yes, with default covering the rest |
| Multi-statement body | statements after the label | block in braces; yield in an expression |
Common mistakes
Comparing strings with ==
Why it goes wrong:
if (plan == "basic")tests whether both references point at the same String object. Text read from input or built at runtime is a different object even when the characters match, so the branch silently never runs.Fix: Use
equals, orequalsIgnoreCasewhen case does not matter.Java · fixif (plan.equals("basic")) { // ... }Forgetting break in a classic switch
Why it goes wrong: With
case 1: ... case 2: ...and nobreak, matching 1 prints the case 1 output and then continues into case 2. Nothing warns you; the program is simply wrong.Fix: Prefer the arrow form, which cannot fall through. If you must use the classic form, end every case with
break.Java · fixswitch (code) { case 1 -> System.out.println("one"); case 2 -> System.out.println("two"); default -> System.out.println("other"); }Dropping the braces and adding a second statement
Why it goes wrong: Without braces only the first statement belongs to the
if. Indenting the second one to match changes nothing for the compiler; it runs unconditionally.Fix: Always write the braces, even for a one-line body.
Java · fixif (stock == 0) { System.out.println("Sold out"); reorder = true; }Ordering branches from widest to narrowest
Why it goes wrong: With
if (score >= 50)beforeelse if (score >= 90), the second branch can never run: every score of 90 or more already satisfied the first test.Fix: Test the most specific condition first, or write both bounds into each condition.
Java · fixif (score >= 90) { grade = "A"; } else if (score >= 50) { grade = "B"; } else { grade = "C"; }
Where you use this
Validation is where conditions earn their keep. A sign-up form should refuse an empty username, reject an age outside a sensible range and only then create the account. Written as a chain, each check reports one clear problem and stops, so the person sees the first thing to fix rather than a wall of messages. The same shape handles command dispatch in a small tool, where a switch on the typed command sends each word to the right piece of code, and it appears inside loops that decide whether to skip an item or stop early, which the loops lesson covers next.
if (name.isBlank()) {
System.out.println("Name is required");
} else if (age < 13 || age > 120) {
System.out.println("Age must be between 13 and 120");
} else {
System.out.println("Account created for " + name);
}Key points
- An
ifcondition must be a boolean expression; there are no truthy values in Java. - An
if/else if/elsechain runs exactly one block: the first whose condition is true. - Order branches from most specific to least specific.
- Always use braces, even around a single statement.
- Compare strings with
equals, never with==. switchwith arrows (Java 14+) has no fall-through and can be an expression that yields a value.- A switch expression must cover every input, so add
defaultfor strings and numbers.
Try it yourself
The program prints pass for a score of 50 or more and fail otherwise. Add branches so that 90 or more prints distinction and 75 to 89 prints merit, keeping pass for 50 to 74.
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int score = in.nextInt();
if (score >= 50) {
System.out.println("pass");
} else {
System.out.println("fail");
}
}
}
82meritimport java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int score = in.nextInt();
if (score >= 90) {
System.out.println("distinction");
} else if (score >= 75) {
System.out.println("merit");
} else if (score >= 50) {
System.out.println("pass");
} else {
System.out.println("fail");
}
}
}
Practise this
Exercises for this lesson are in the Java practice set.
Related lessons
- Operators in JavaJava's arithmetic, comparison, logical and assignment operators: integer division, remainder, short-circuit evaluation and precedence, with runnable examples.9 min
- Loops in Java: for, while and do-whileHow Java repeats work with for, while and do-while loops, when each fits, what break and continue do, and how to avoid off-by-one and infinite loops.9 min
- Strings in JavaHow Java strings work: immutability, the methods you use daily, why equals not == compares text, trimming and splitting input, StringBuilder and String.format.10 min
Frequently asked questions
Can Java switch on a String?
Yes, since Java 7. The cases are string literals and matching uses the same character comparison as equals, so it is safe for text that came from input. Matching is case-sensitive; normalise with toLowerCase() first if the case should not matter. A switch expression on a String needs a default because the compiler cannot know every possible value.
When should I use switch instead of if-else?
Use switch when one value is compared against a set of fixed constants: a menu choice, a status code, a day name. It reads as a table and the arrow form guarantees one branch runs. Use if/else if when the conditions are ranges, combine several variables, or need && and ||; a switch cannot express score >= 90.
How this page was checked. Every program on it was run with OpenJDK 21 at build time by the publishing checks, and the output shown is what it printed. Running Java inside the browser is not available yet, so the Run button is absent rather than pretending; copy the code and run it with OpenJDK 21 locally.