# Conditional Statements

Course: [Java](https://www.devtutorials.ai/learn/java) · Section: Control Flow
Source: https://www.devtutorials.ai/learn/java/control-flow/conditional-statements

> Make decisions in Java with if, if-else, else-if ladders, nested conditions, combined conditions, the ternary operator and switch.

Conditional statements let Java choose a path.

Think of checking the weather before you leave home. If it is raining, you take an umbrella. If it is not, you leave it behind.

Programs make choices in the same way. They check a condition, then decide what to run next.

## What You Will Learn

In this lesson, you will learn:

1. Why programs need to make decisions.
2. How to write `if`, `if-else`, and `else-if` statements.
3. How to put one condition inside another.
4. How to build conditions with comparisons, `&&`, `||`, and `!`.
5. How to choose between two values with the ternary operator.
6. How to choose between many fixed values with `switch`.
7. When to use `switch` and when to use `if-else`.

## Start With a Working Example

Press **Run**.

```java runnable title="One condition decides which message prints"
public class Main {
    public static void main(String[] args) {
        int temperature = 32;

        if (temperature > 30) {
            System.out.println("It is hot. Drink some water.");
        } else {
            System.out.println("The weather is fine.");
        }

        System.out.println("Have a good day!");
    }
}
```

Expected output:

```text
It is hot. Drink some water.
Have a good day!
```

`32 > 30` is true, so Java runs the first block and skips the `else` block.

The last line is outside both blocks. It always runs.

### Try This

Change `temperature` to `25`. Run it again. The first message changes, but the last line stays the same.

## Why Conditional Statements Are Needed

Without conditions, a program runs every line from top to bottom, every time. It always does the same thing.

Real programs must react to what happens:

- A login page lets you in only if the password is correct.
- A shop gives a discount only if the bill is big enough.
- A game ends only if the player has no lives left.

A conditional statement lets the program **choose** which code to run. This is called **control flow**, because you control the path the program follows.

## Syntax

Every conditional statement has two parts:

- a **condition** inside brackets `( )`, which must be `true` or `false`;
- a **block** of code inside curly braces `{ }`, which runs when the condition is true.

```text
if (condition) {
    // code that runs when the condition is true
}
```

The condition must give a `boolean`. Java does not treat numbers as true or false. So `if (1)` does not compile.

## `if` Statement

An `if` statement runs its block only when the condition is true. If the condition is false, Java skips the block and carries on.

```java runnable title="The block runs only when the condition is true"
public class Main {
    public static void main(String[] args) {
        int cartTotal = 1200;

        System.out.println("Cart total: " + cartTotal);

        if (cartTotal >= 1000) {
            System.out.println("You get free delivery!");
        }

        System.out.println("Thank you for shopping.");
    }
}
```

Expected output:

```text
Cart total: 1200
You get free delivery!
Thank you for shopping.
```

Change `cartTotal` to `800`. The free delivery line disappears. The other two lines still print.

Always use curly braces, even for one line. Without them, only the very next line belongs to the `if`. A second line you add later will run every time, and that bug is hard to see.

## `if-else` Statement

An `if-else` statement gives Java two paths. Exactly one of them runs.

- If the condition is true, the `if` block runs.
- If the condition is false, the `else` block runs.

```java runnable title="Exactly one of the two blocks runs"
public class Main {
    public static void main(String[] args) {
        int age = 16;

        if (age >= 18) {
            System.out.println("You can vote.");
        } else {
            System.out.println("You can vote in " + (18 - age) + " years.");
        }
    }
}
```

Expected output:

```text
You can vote in 2 years.
```

`16 >= 18` is false, so the `else` block runs.

Think of a fork in a road. You must take one path or the other. You can never take both, and you can never take neither.

## `else-if` Ladder

Sometimes there are more than two choices. An **else-if ladder** checks conditions one after another, from top to bottom.

Java runs the block of the **first** condition that is true. Then it skips everything else in the ladder.

```java runnable title="The first true condition wins"
public class Main {
    public static void main(String[] args) {
        int marks = 76;
        String grade;

        if (marks >= 90) {
            grade = "A";
        } else if (marks >= 75) {
            grade = "B";
        } else if (marks >= 60) {
            grade = "C";
        } else if (marks >= 40) {
            grade = "D";
        } else {
            grade = "F";
        }

        System.out.println("Marks: " + marks + ", Grade: " + grade);
    }
}
```

Expected output:

```text
Marks: 76, Grade: B
```

Java checks `76 >= 90` first. That is false. Then it checks `76 >= 75`. That is true, so `grade` becomes `"B"`.

`76 >= 60` is also true. But Java never checks it, because it already found a match.

The final `else` catches everything that matched nothing above it.

In a ladder, order matters. Put the strictest condition first. If you check `marks >= 40` first, a mark of 95 would get a `D`, because `95 >= 40` is true and Java stops there.

## Nested Conditions

A **nested condition** is an `if` statement inside another `if` statement.

Use it when a second question only makes sense after the first answer is yes.

Think of entering a theme park ride. First the guard checks your ticket. Only if you have one does the guard check your height.

```java runnable title="The inner check runs only when the outer check passes"
public class Main {
    public static void main(String[] args) {
        boolean hasTicket = true;
        int height = 125;

        if (hasTicket) {
            if (height >= 130) {
                System.out.println("Enjoy the ride!");
            } else {
                System.out.println("Sorry, you must be 130 cm or taller.");
            }
        } else {
            System.out.println("Please buy a ticket first.");
        }
    }
}
```

Expected output:

```text
Sorry, you must be 130 cm or taller.
```

The outer `if` passes, because `hasTicket` is true. So Java checks the inner `if`. `125 >= 130` is false, so the inner `else` runs.

Try to keep nesting shallow. Two levels is fine. Four or five levels become hard to read.

## Boolean Expressions

A **boolean expression** is any expression that gives `true` or `false`.

The condition of every `if` statement is a boolean expression.

You can build one in several ways:

- a comparison, like `age >= 18`;
- a `boolean` variable, like `isLoggedIn`;
- a method that returns a `boolean`, like `name.isEmpty()`;
- several of these joined with `&&`, `||`, or `!`.

```java runnable title="Store a condition in a variable with a clear name"
public class Main {
    public static void main(String[] args) {
        int balance = 2500;
        int price = 1800;

        boolean canAfford = balance >= price;

        if (canAfford) {
            System.out.println("Purchase approved.");
        }

        System.out.println("Can afford: " + canAfford);
    }
}
```

Expected output:

```text
Purchase approved.
Can afford: true
```

Storing the condition in `canAfford` gives it a name. The `if` line now reads almost like English.

Write `if (canAfford)`, not `if (canAfford == true)`. The variable is already true or false, so the extra comparison adds nothing.

## Combined Conditions

Often one fact is not enough. You need to check two or more facts together. Java joins conditions with logical operators.

### AND (`&&`)

`&&` is true only when **both** conditions are true.

### OR (`||`)

`||` is true when **at least one** condition is true.

### NOT (`!`)

`!` flips a condition. It turns `true` into `false` and `false` into `true`.

```java runnable title="AND, OR and NOT in real decisions"
public class Main {
    public static void main(String[] args) {
        int age = 22;
        boolean hasLicence = true;
        String day = "Sunday";
        boolean isRaining = false;

        if (age >= 18 && hasLicence) {
            System.out.println("You may drive.");
        }

        if (day.equals("Saturday") || day.equals("Sunday")) {
            System.out.println("It is the weekend.");
        }

        if (!isRaining) {
            System.out.println("No umbrella needed.");
        }
    }
}
```

Expected output:

```text
You may drive.
It is the weekend.
No umbrella needed.
```

You need to be old enough **and** have a licence to drive. Either weekend day counts, so the second check uses **or**. `!isRaining` reads as "not raining".

### Checking a Range

To check that a number is between two values, join two comparisons with `&&`.

```text
if (score >= 50 && score <= 100)
```

You cannot write `50 <= score <= 100` in Java. That does not compile.

| Operator | True when | Example |
|---|---|---|
| `&&` | both sides are true | `age >= 18 && hasLicence` |
| `\|\|` | at least one side is true | `isAdmin \|\| isOwner` |
| `!` | the condition is false | `!isEmpty` |

## Ternary Operator

The ternary operator is a short `if-else` that **gives back a value**.

```text
condition ? valueIfTrue : valueIfFalse
```

```java runnable title="A ternary chooses a value in one line"
public class Main {
    public static void main(String[] args) {
        int stock = 0;
        int items = 3;

        String status = stock > 0 ? "In stock" : "Out of stock";
        String word = items == 1 ? "item" : "items";

        System.out.println(status);
        System.out.println("You have " + items + " " + word + " in your cart.");
    }
}
```

Expected output:

```text
Out of stock
You have 3 items in your cart.
```

`stock > 0` is false, so `status` gets `"Out of stock"`.

The second line picks `"item"` or `"items"` so the sentence reads correctly.

Use the ternary operator when you need to **choose a value**. Use `if-else` when you need to **run several statements**.

## Switch Statement

### Why `switch` Exists

Sometimes you compare one variable against many fixed values. A long else-if ladder works, but it repeats the variable on every line.

```text
if (day == 1) { ... }
else if (day == 2) { ... }
else if (day == 3) { ... }
// and so on, up to 7
```

A `switch` statement does the same job in a cleaner way. You name the variable once. Then you list the values it might have.

Think of a lift. You press one floor number, and the lift goes straight to that floor. It does not stop at every floor to ask.

### `switch` Syntax

```text
switch (expression) {
    case value1:
        // code for value1
        break;
    case value2:
        // code for value2
        break;
    default:
        // code when nothing matches
}
```

The expression can be an `int`, `char`, `String`, a few other whole-number types, or an `enum`. It cannot be a `double`, a `float`, a `long`, or a `boolean`.

A `switch` on a `String` is case sensitive. `case "yes":` does not match `"Yes"`. Convert the text first with `answer.toLowerCase()` if capital letters should not matter.

### `case` Labels

Each `case` label names one value. When the expression matches it, Java jumps to that label and starts running from there.

Each value must be a fixed literal or constant. Two labels cannot have the same value.

### `break` Statement

`break` ends the `switch`. Java jumps to the first line after the closing brace.

### `default` Case

`default` runs when no `case` matches. It works like the final `else` in a ladder.

It is optional, but it is a good habit. It catches values you did not plan for.

```java runnable title="switch jumps straight to the matching case"
public class Main {
    public static void main(String[] args) {
        int day = 3;
        String dayName;

        switch (day) {
            case 1:
                dayName = "Monday";
                break;
            case 2:
                dayName = "Tuesday";
                break;
            case 3:
                dayName = "Wednesday";
                break;
            case 4:
                dayName = "Thursday";
                break;
            case 5:
                dayName = "Friday";
                break;
            default:
                dayName = "Weekend";
        }

        System.out.println("Day " + day + " is " + dayName);
    }
}
```

Expected output:

```text
Day 3 is Wednesday
```

`day` is `3`, so Java jumps to `case 3`. It sets `dayName` and reaches `break`, which ends the `switch`.

### What Happens Without `break`

If you leave out `break`, Java does not stop at the end of a case. It keeps running the cases below. This is called **fall-through**.

```java runnable title="Without break, Java falls through to the next cases"
public class Main {
    public static void main(String[] args) {
        int level = 2;

        switch (level) {
            case 1:
                System.out.println("Unlocked: Sword");
            case 2:
                System.out.println("Unlocked: Shield");
            case 3:
                System.out.println("Unlocked: Map");
        }
    }
}
```

Expected output:

```text
Unlocked: Shield
Unlocked: Map
```

Java jumps to `case 2`. There is no `break`, so it carries on and runs `case 3` too.

Fall-through is usually a mistake. Sometimes it is useful, when several values share the same code:

```java runnable title="Several cases can share one block"
public class Main {
    public static void main(String[] args) {
        char grade = 'B';

        switch (grade) {
            case 'A':
            case 'B':
                System.out.println("Well done!");
                break;
            case 'C':
                System.out.println("Good effort.");
                break;
            default:
                System.out.println("Keep practising.");
        }
    }
}
```

Expected output:

```text
Well done!
```

`'A'` and `'B'` share the same message. `case 'A':` has no code, so it falls through to `case 'B':`.

### The Arrow Form

Since Java 14, `switch` also has a shorter **arrow** form. Each case uses `->`, and there is no fall-through, so you do not need `break`.

A `switch` written this way can also give back a value.

```java runnable title="The arrow form needs no break and returns a value"
public class Main {
    public static void main(String[] args) {
        String size = "M";

        int price = switch (size) {
            case "S" -> 199;
            case "M" -> 249;
            case "L", "XL" -> 299;
            default -> 0;
        };

        System.out.println("Price of size " + size + ": " + price);
    }
}
```

Expected output:

```text
Price of size M: 249
```

`case "L", "XL"` lists two values for one result. The `;` after the closing brace is needed, because the whole `switch` is part of one statement.

### `switch` vs `if-else`

| | `switch` | `if-else` |
|---|---|---|
| Best for | One variable against many fixed values | Ranges and complex conditions |
| Can check ranges like `marks >= 75`? | No | Yes |
| Can join conditions with `&&` and `\|\|`? | No | Yes |
| Works with | `int`, `char`, `String`, `enum`, and some others | Any boolean expression |
| Needs `break`? | Yes, in the classic form | No |
| Readability with many values | Clean and easy to scan | Long and repetitive |

In simple words: use `switch` to match exact values. Use `if-else` to test conditions.

## Common mistakes

The following mistakes are common when writing conditions and `switch` statements. Each row shows what you see, why it happens and how to fix it.

| Symptom | Cause | Fix |
|---|---|---|
| `int cannot be converted to boolean` | `=` was used in the condition | Use `==` |
| The `if` block runs every time | A `;` straight after the condition | Remove the `;` |
| A high mark gets a low grade | A wide condition comes first in the ladder | Put the strictest condition first |
| Extra lines print after the matching case | `break` is missing | End each case with `break` |
| A text match fails even when the text is the same | `==` was used on a `String` | Use `.equals()` |
| `cannot find symbol` for a variable set inside an `if` | The variable was declared inside the block | Declare it before the `if` |

## What to Remember

- A conditional statement runs code only when its condition is `true`.
- `if` runs one block or nothing. `if-else` always runs exactly one of two blocks.
- An else-if ladder stops at the first true condition, so put the strictest condition first.
- Join conditions with `&&` (both), `||` (either), and `!` (not). Use `.equals()` to compare text.
- The ternary operator chooses a value. `if-else` chooses which statements to run.
- `switch` matches one value against fixed cases. End each classic case with `break`, and add a `default`.

Next: Loops
