if-else Statement
Every useful program needs to make decisions. The if-else statement is Java’s primary way of saying “do this only when a condition is true, otherwise do something else.” It is one of the first things you learn and one of the last things you stop using.
The Simple if Statement
The most basic form checks a condition and runs a block of code only when it evaluates to true.
int temperature = 35;
if (temperature > 30) {
System.out.println("It's a hot day!");
}
Output:
It's a hot day!
The condition inside the parentheses must be a boolean expression — something that resolves to either true or false. Java does not allow integers here (unlike C/C++); if (1) is a compile-time error.
Tip: Always use curly braces
{}even for single-statement bodies. Omitting them is legal but invites bugs when you later add a second statement.
if-else — Two-Way Decision
Add an else block to handle the false case.
int score = 55;
if (score >= 60) {
System.out.println("You passed!");
} else {
System.out.println("You need to study more.");
}
Output:
You need to study more.
Exactly one of the two branches runs — never both, never neither.
if-else-if Ladder — Multiple Conditions
Chain else if blocks to test several mutually exclusive conditions in order. Java evaluates them top-to-bottom and executes the first branch whose condition is true.
int marks = 78;
if (marks >= 90) {
System.out.println("Grade: A");
} else if (marks >= 80) {
System.out.println("Grade: B");
} else if (marks >= 70) {
System.out.println("Grade: C");
} else if (marks >= 60) {
System.out.println("Grade: D");
} else {
System.out.println("Grade: F");
}
Output:
Grade: C
The trailing else is optional but recommended — it acts as a catch-all for anything that falls through all the conditions.
Warning: Order matters. If you put
marks >= 60beforemarks >= 70, a score of 78 would incorrectly printGrade: Dand stop — the remaining conditions would never be reached.
Nested if-else
You can place an if-else inside another if-else block to test a secondary condition only after a primary one passes.
int age = 20;
boolean hasTicket = true;
if (age >= 18) {
if (hasTicket) {
System.out.println("Welcome! Enjoy the show.");
} else {
System.out.println("You need a ticket to enter.");
}
} else {
System.out.println("Sorry, you must be 18 or older.");
}
Output:
Welcome! Enjoy the show.
Tip: More than two levels of nesting usually signals a chance to refactor — consider extracting a helper method or combining conditions with
&&/||from the operators page.
Combining Conditions with Logical Operators
You can build compound conditions using && (AND), || (OR), and ! (NOT) without nesting.
int speed = 85;
boolean isFoggy = true;
if (speed > 80 || isFoggy) {
System.out.println("Slow down — conditions are dangerous.");
}
int n = 15;
if (n > 0 && n % 2 != 0) {
System.out.println(n + " is a positive odd number.");
}
Output:
Slow down — conditions are dangerous.
15 is a positive odd number.
Java uses short-circuit evaluation: with &&, if the left side is false, the right side is never evaluated. With ||, if the left side is true, the right side is skipped. This is both a performance benefit and a useful safety technique (e.g., checking obj != null && obj.isReady()).
The Ternary Operator — Inline if-else
For simple two-branch assignments, the ternary operator ? : is a compact alternative.
int age = 20;
String status = (age >= 18) ? "adult" : "minor";
System.out.println("Status: " + status);
Output:
Status: adult
The syntax is condition ? valueIfTrue : valueIfFalse. It must produce a value, so it works well inside assignments and method arguments. Avoid nesting ternary operators — the result is nearly unreadable.
When to Use if-else vs switch
| Situation | Prefer |
|---|---|
| Testing a range or complex boolean | if-else |
| Testing one variable against many fixed values | switch |
| Java 14+ and the values are known constants | switch expression |
Mixed types or null checks | if-else |
For equality checks on a single integer, string, or enum, a switch statement is often cleaner and can be slightly faster (jump table optimization by the JVM).
Practical Example — FizzBuzz
public class FizzBuzz {
public static void main(String[] args) {
for (int i = 1; i <= 20; i++) {
if (i % 15 == 0) {
System.out.println("FizzBuzz");
} else if (i % 3 == 0) {
System.out.println("Fizz");
} else if (i % 5 == 0) {
System.out.println("Buzz");
} else {
System.out.println(i);
}
}
}
}
Output (first 6 lines):
1
2
Fizz
4
Buzz
Fizz
Notice that i % 15 == 0 is tested first — if you tested i % 3 == 0 first, multiples of 15 would print “Fizz” instead of “FizzBuzz.”
Under the Hood
When the Java compiler sees an if-else, it emits conditional branch bytecode instructions. For a simple if (x > 0) block the compiler produces something like:
iload_1 // push x onto the operand stack
ifle <else> // if x <= 0, jump to else branch
... (then-body instructions)
goto <end>
<else>: ... (else-body instructions)
<end>:
The JIT compiler takes this further. Once a branch has been executed many times, the JIT applies branch prediction heuristics and can speculatively inline the hot path, deopting only if the cold branch is suddenly taken. This means a well-structured if-else-if ladder over a stable condition can run extremely fast in a hot loop — the JVM effectively eliminates the overhead of checking conditions it has never seen fire.
For deeply nested chains over integer equality, the compiler may replace the ladder with a lookup table or table switch, turning O(n) comparisons into O(1) array indexing. This is one reason well-structured code with clear constant conditions can outperform creative bitwise hacks.
See JIT Compilation & Bytecode for a deeper look at how this optimization process works.
Common Mistakes
- Using
=instead of==—if (x = 5)is a compile-time error in Java (unlike C), so the compiler has your back, but still watch out. - Floating-point equality — never write
if (d == 0.1). Floating-point representation is inexact; useMath.abs(d - 0.1) < 1e-9instead. - Dangling else — in the rare case you skip braces across multiple ifs, an
elsealways pairs with the nearest precedingif. Braces eliminate the ambiguity entirely. - Redundant boolean comparison — write
if (isReady), notif (isReady == true). The latter is harmless but verbose.
Related Topics
- switch Statement — cleaner multi-branch logic when comparing one variable against constant values
- Operators — the comparison and logical operators (
==,!=,&&,||) that power your conditions - Control Statements — overview of all Java control-flow constructs
- for Loop — combining conditions with loops to iterate selectively
- Ternary and Switch Expressions — modern Java expression forms that can replace verbose if-else chains
- Common Mistakes & Pitfalls — deeper look at the bugs that catch developers off guard