Java Conditions

BEGINNER ~8 min read Tutorial

Conditional statements let your program make decisions. Java provides three forms: if, if/else, and switch. Each chooses which block of code to execute based on a boolean condition or a value match.

This tutorial covers all three with worked examples. We also cover the new switch expression form introduced in Java 14, which returns a value — more concise and safer than the traditional statement form.

1. The if Statement

The simplest conditional runs a block only when a boolean expression is true:

java
int age = class="tok-num">20;

if (age >= class="tok-num">18) {
    System.out.println("You can vote.");
}

class=class="tok-str">"tok-cmt">// single statement - braces optional but recommended
if (age >= class="tok-num">18) System.out.println("Adult.");

The condition must evaluate to a boolean. Java does not implicitly convert integers to booleans the way C does, so if (count) does not compile.

2. if / else

Add an else branch to run when the condition is false:

java
int score = class="tok-num">75;

if (score >= class="tok-num">90) {
    System.out.println("A");
} else if (score >= class="tok-num">80) {
    System.out.println("B");
} else if (score >= class="tok-num">70) {
    System.out.println("C");
} else {
    System.out.println("F");
}

You can chain multiple conditions with else if. Conditions are evaluated top to bottom; the first one that matches wins, and the rest are skipped.

3. The Ternary Operator

For simple binary choices, the ternary operator ?: is more concise:

java
int score = class="tok-num">75;
String grade = (score >= class="tok-num">60) ? "pass" : "fail";

class=class="tok-str">"tok-cmt">// null-safe default
String input = null;
String normalized = (input == null) ? "" : input.trim();

Use it for short expressions only. Nested ternaries quickly become unreadable.

4. The switch Statement

When you have many branches on the same value, switch is cleaner than a long chain of else if. It works on byte, short, char, int, their wrapper types, String (since Java 7), and any enum.

java
int day = class="tok-num">3;
switch (day) {
    case class="tok-num">1:
        System.out.println("Monday");
        break;
    case class="tok-num">2:
        System.out.println("Tuesday");
        break;
    case class="tok-num">3:
        System.out.println("Wednesday");
        break;
    class=class="tok-str">"tok-cmt">// ... and so on
    case class="tok-num">6:
    case class="tok-num">7:   class=class="tok-str">"tok-cmt">// fall-through intentional: both are weekend
        System.out.println("Weekend");
        break;
    default:
        System.out.println("Invalid day");
}
Watch the fall-through

Without break, execution falls through to the next case. This is occasionally useful (grouping cases), but more often a bug. Always end each case with break unless you intend to fall through.

5. The switch Expression

Java 14 introduced the switch expression, which returns a value. Combined with arrow labels, it eliminates the fall-through footgun:

java
int day = class="tok-num">3;
String name = switch (day) {
    case class="tok-num">1 -> "Monday";
    case class="tok-num">2 -> "Tuesday";
    case class="tok-num">3 -> "Wednesday";
    case class="tok-num">4 -> "Thursday";
    case class="tok-num">5 -> "Friday";
    case class="tok-num">6 -> "Saturday";
    case class="tok-num">7 -> "Sunday";
    default -> "Invalid";
};

class=class="tok-str">"tok-cmt">// with a block and yield
int score = class="tok-num">75;
String grade = switch (score / class="tok-num">10) {
    case class="tok-num">9, class="tok-num">10 -> "A";
    case class="tok-num">8 -> "B";
    case class="tok-num">7 -> "C";
    case class="tok-num">6 -> "D";
    default -> {
        System.out.println("Failed");
        yield "F";
    }
};

The arrow form case L -> ... runs only the right-hand side and does not fall through. Each arm can be a single expression, a block, or a throw.

6. Pattern Matching in switch (Java 21)

Since Java 21, switch can match on the runtime type of an object and bind a pattern variable, replacing long instanceof chains:

java
Object obj = "Hello";

String result = switch (obj) {
    case Integer i -> "Integer: " + i;
    case String s  -> "String of length " + s.length();
    case Double d  -> "Double: " + d;
    case int[] arr -> "int array of length " + arr.length;
    case null      -> "null";
    default        -> "Unknown: " + obj;
};
class=class="tok-str">"tok-cmt">// result is "String of length class="tok-num">5"

This is the modern Java way to write type-based dispatch. The compiler checks that all cases are covered when the type is sealed — an especially powerful combination with the sealed keyword.

7. Switching on Strings

Switching on a String works since Java 7. The comparison is case-sensitive and uses .equals() internally, so you do not need to worry about reference equality:

java
String command = "start";

switch (command) {
    case "start":
        startService();
        break;
    case "stop":
        stopService();
        break;
    case "status":
        printStatus();
        break;
    default:
        System.err.println("Unknown command: " + command);
}

8. Truthiness and Pitfalls

Pitfall: = instead of ==

Writing if (x = 5) assigns 5 to x and evaluates to the assigned value. For int this does not compile, but for boolean it silently does — a classic bug. Use == for comparison.

Pitfall: comparing strings with ==

if (input == "yes") compares references, not text. Always use if (input.equals("yes")) or, for null-safety, if ("yes".equals(input)).

Exercises

  1. Write a method that takes an int score and prints “A”, “B”, “C”, “D” or “F” using an if/else-if chain.
  2. Rewrite the same logic using a switch expression.
  3. Write a method that takes a DayOfWeek enum and prints “weekday” or “weekend”.
  4. Use a pattern switch to dispatch on the type of an Object: String, Integer, double[] and default.