JAVA FUNDAMENTALSLesson 04
Control Flow Statements

// Java Fundamentals · Lesson 04

Control Flow Statements

So far every program ran from top to bottom, every line exactly once. Now your program makes decisions: it checks a condition and chooses which lines run.

BY THE END OF THIS LESSON YOU CAN

  • Read and draw a flowchart of a decision
  • Write if, else and else if chains and nested ifs, without the classic traps
  • Pick a value with the ternary operator ?:
  • Write switch statements, classic with break and the arrow form, and switch expressions with yield
  • Choose between if, switch and ?: for a problem
23 °C
Weather advice · inside main(…)

          

        

Part 1 of 7

Making decisions with if

A condition is a question with a yes or no answer. if runs a block of code only when the answer is yes.

// 1.1

A straight line or a fork in the road

A flowchart draws a program as shapes and arrows. Until now your programs were a straight line. A decision adds a fork: the program takes one path or the other, never both.

OvalStart or end of the program
RectangleAn action: assign, calculate, print
DiamondA decision: a yes/no question, a boolean
ArrowWhich step runs next

Sequential

every step runs once

Each step runs once, in order. This is every program you have written so far.

Branching: an ATM

// 1.2

Anatomy of an if

An if statement runs its block only when the condition is true. When it is false, Java skips the block and carries on after the }. Click any part.

Main.java
if (balance >= amount) {
    balance = balance - amount;
}

Start with the condition: its value must be true or false.

Inside main(…)
int balance = 120;
int amount = 50;
if (balance >= amount) {
    balance = balance - amount;
}
System.out.println(balance);
$ java Main
70

Java is stricter than C

In C and JavaScript, if (count) means “if count is not zero”. In Java the condition must be a boolean. A number is not a yes or no answer, so this doesn’t compile.

Say what you mean: if (count > 0). The same goes for if (1): it doesn’t compile either.

Main.java
public class Main {
    public static void main(String[] args) {
        int count = 3;
        if (count) {
            System.out.println("You have messages");
        }
    }
}
$ javac Main.java
Main.java:4: error: incompatible types: int cannot be converted to boolean
        if (count) {
            ^
1 error

// 1.3

Braces are optional. Write them anyway.

Without { }, an if controls only the one statement right after it. Indentation means nothing to Java. Run the code, then add the braces.

Inside main(…)

          

        

Rule for this course: always write the braces, even for one line. IntelliJ’s Reformat Code (Ctrl+Alt+L, on a Mac ⌘+⌥+L) fixes the indentation, and then this bug is easy to see.

// Apple, February 2014 · CVE-2014-1266

“goto fail”: one extra line broke secure connections

Apple’s code for secure connections (TLS, the “S” in HTTPS) is written in C, which has the same rule about braces. One line was accidentally duplicated:

sslKeyExchange.c · C, shortened

        

The marked goto fail; looks like part of the if above it, but it isn’t. It always runs and jumps past the last step, the check of the server’s signature. err still held 0, meaning “no error”, so the connection was accepted. Anyone on the same Wi-Fi could pretend to be your bank. Apple fixed it in iOS 7.0.6 and OS X 10.9.2.

// 1.4

if and else: exactly one of two

Add an else block and the program always does one of two things: never both, and never neither. Pick a scenario and step through it like a debugger.

Inside main(…)

        

      

Memory

// 1.5

Writing good conditions

A condition is any expression whose value is a boolean. Everything from lesson 3 works here: comparisons, &&, ||, ! and .equals.

Give a long condition a name

Store it in a boolean with a clear name. The if then reads like a sentence. Change the values:

20

          

        

Combine with && and ||

if (age >= 18 && hasTicket) {
    System.out.println("Come in");
}
if (day == 6 || day == 7) {
    System.out.println("Weekend");
}

Compare Strings with .equals

if (city.equals("Baku")) {
    System.out.println("Capital");
}

== checks whether two variables point to the same String object, not whether the text is the same. Part 2 shows the trap.

Don’t compare a boolean with true

Instead ofWrite if (isActive == true)if (isActive) if (isActive == false)if (!isActive)

A boolean already is true or false. Comparing it with true adds nothing, and one missing = turns it into a bug (Part 2).

// 1.6

Checkpoint: making decisions

Eight quick questions on Part 1. Pick an answer to see why it is right or wrong.

Part 2 of 7

Chains, nesting and traps

Real decisions have more than two outcomes. Chain conditions, put one if inside another, and learn the traps that catch every beginner.

// 2.1

else if: the first true condition wins

Java checks the conditions from top to bottom and runs the block of the first one that is true. The conditions below it are not even checked. Move the slider, then try the other versions.

Grades · inside main(…)

        

      
78
78

VERSION

// 2.2

Nested ifs: a login check

An if can sit inside another if. Here a login passes three checks in order. Flip the facts, then compare three ways to write the same logic.

Login · inside main(…)

        

      

// 2.3

The dangling else: indentation lies

Nested ifs without braces raise a question: which if does the else belong to? Java’s rule: an else belongs to the nearest if above it that has no else yet. Indentation has no say.

Values
View
Inside main(…)

          

        

Read the colors

An if and the else that belongs to it get the same color. In As written, the colors show what the indentation suggests. Switch to As Java reads it to see the truth.

// 2.4

Seven classic traps

Two of these don’t compile. The dangerous ones compile fine and quietly do the wrong thing. Pick a trap to see what really happens and how to fix it.

// 2.5

Game: which line prints?

Fourteen short programs. Read the code, predict the exact output and pick it. Every answer was checked with Java 25.

// 2.6

Checkpoint: chains, nesting and traps

Eight questions on Part 2. Several of them hide one of the traps.

Part 3 of 7

The ternary operator ?:

Sometimes you don’t want to do something, you just want to pick a value. Java’s only operator with three operands does exactly that.

// 3.1

An if that gives you a value

condition ? valueIfTrue : valueIfFalse. If the condition is true, the whole expression becomes the first value, otherwise the second. It has three operands, so it is called the ternary operator. Click any part.

Main.java
String status =
    age >= 18 ? "adult" : "minor";
20
statement

if does something

It runs a block or skips it. It has no value, so you can’t write String s = if (…).

expression

?: is something

It has a value and a type, so it fits anywhere a value fits: after =, inside println(…), in a + chain.

// 3.2

From if/else to ?:

When both branches only choose a value for the same thing, a ternary says it in one line. Pick an example and morph it. The colors show which part goes where.

Inside main(…)

          

        
conditionvalue if truevalue if false

// 3.3

Rules and traps of ?:

The ternary is small, but it follows strict rules. Pick a rule to see what goes wrong and how to write it instead.

// 3.4

Game: pick the ternary

Each round gives you an if/else or a task. Pick the one ternary that does exactly the same. The wrong ones swap the branches, flip the condition, get the type wrong or forget the brackets.

// 3.5

Checkpoint: the ternary operator

Eight questions on Part 3.

Part 4 of 7

The switch statement

When one variable is compared with many fixed values, switch is cleaner than a long else if chain. It also has a famous trap.

// 4.1

Anatomy of a switch

A switch looks at one value, jumps straight to the case with the same value, and runs from there. Click any part, and change day to see which lines run.

Inside main(…)

          

        
day =

When a switch fits

One variable, compared for equality with many fixed values: a menu option, a day number, a command, a grade letter. It replaces a chain like if (day == 1) … else if (day == 2) … and says “pick one of these” more clearly.

// 4.2

What can you switch on?

The value in switch (…) is called the selector. Only some types are allowed. Try each one.

Main.java

          

        

Selector types

  • allowedint short byte char, their wrappers (Integer …), String, and enums (a later lesson)
  • not allowedlong float double boolean

// 4.3

case labels: fixed values, each one once

javac decides where each case jumps to before the program runs, so a label must be a value it already knows. Try the three versions.

Main.java

          

        

What a label can be

  • A literal of the selector’s type: case 1:, case 'A':, case "Baku":
  • A final constant: final int SATURDAY = 6; then case SATURDAY:
  • Not a normal variable, not a range like >= 90, and never the same value twice

// 4.4

Fall-through lab

A switch jumps in at the matching case, then runs line after line, straight through the next case labels. Only break gets you out. Remove some breaks and press Run.

day =
break after
Inside main(…)

        
Output

          

// 4.5

Fall-through on purpose, and other selectors

Fall-through is not always a bug. Stack labels to share one block. Then switch on text and characters, and see the one value a switch can’t handle.

Inside main(…)

        

      

// 4.6

Checkpoint: the switch statement

Eight questions on Part 4. Watch out for missing breaks.

Part 5 of 7

Modern switch

Arrow labels and switch expressions, standard since Java 14, remove the fall-through trap and let a switch produce a value.

// 5.1

Arrow labels: no fall-through, no break

Write case … -> instead of case …: and a case runs only its own code. There is nothing to fall through and no break to forget. Same logic, two forms:

day =
Inside main(…)

          

        

Rules of the arrow form

  • The code after -> runs, then the switch is finished. No fall-through.
  • Several values share a case: case 6, 7 ->, separated by commas.
  • One statement after the arrow, or a block { … } for several.
  • Don’t mix the forms: -> and : in one switch is a compile error.

Several statements? Use a block

int day = 6;
switch (day) {
    case 6, 7 -> {
        System.out.println("Weekend");
        System.out.println("Open at 10");
    }
    default -> System.out.println("Open at 9");
}
$ java Main
Weekend
Open at 10

// 5.2

Switch expressions: a switch with a value

Put a switch after = and it becomes an expression, like the ternary: every case gives a value. It must give a value for every possible input, and the statement ends with ; after the }.

day =
Main.java

          

        

yield: the value of a block

When a case needs a block { … }, yield gives the value of the block. Think of it as “this is the answer”.

int day = 6;
int hours = switch (day) {
    case 6, 7 -> {
        System.out.println("Weekend!");
        yield 0;
    }
    default -> 8;
};
System.out.println("Work hours: " + hours);
$ java Main
Weekend!
Work hours: 0

The classic form works too

With colons, every path needs its own yield, and fall-through still exists. Prefer arrows.

int day = 2;
int hours = switch (day) {
    case 6:
    case 7:
        yield 0;
    default:
        yield 8;
};
System.out.println(hours);
$ java Main
8

// 5.3

if, switch or ?:?

All three make decisions, and each is best at a different job. Read the table, then sort eleven real tasks.

UseWhen you want to…Example
?:choose between two valuesa > b ? a : b
iftest ranges or combined conditions, or do something only sometimesscore >= 90 && !late
switchcompare one variable with many fixed valuescase 1, 2, 3 ->

A switch can’t test a range: there is no case >= 90, because labels are fixed values. In new code, prefer arrow labels and switch expressions to the classic form.

// Coming later · Java 21

Pattern matching for switch

A case can also check the type of a value and add a condition with when. Object can hold a value of any type. You will use this once we have classes.

Object value = 42;
String text = switch (value) {
    case Integer i when i > 0 -> "positive number";
    case Integer i -> "number";
    case String s -> "text: " + s;
    default -> "something else";
};
System.out.println(text);
$ java Main
positive number

// 5.4

Game: what does this switch print?

Twelve switches: classic and arrow, statements and expressions. Some fall through, some don’t. Every answer was checked with Java 25.

// 5.5

Checkpoint: modern switch

Eight questions on Part 5.

Part 6 of 7

Putting it together

One small program that uses everything from this lesson, and the compiler errors you will meet most often.

// 6.1

Mini-program: a cinema ticket

A switch expression picks the base price, an else if chain applies the age rules, and a ternary handles the student discount. Change the customer and watch which lines run.

20
day
  • Base price: Monday to Friday 8 AZN, Saturday and Sunday 12 AZN
  • Children under 12 pay half
  • Seniors aged 65 or more pay 3 AZN less
  • Students (everyone else) pay 2 AZN less

WHAT HAPPENED

    Cinema · inside main(…)
    
            
    
          

    // 6.2

    Break it on purpose

    These are the mistakes you will make this week. Most of them javac catches for you, with the exact messages below. The last one compiles and is simply wrong. Pick a mistake to see the error and the fix.

    // 6.3

    Checkpoint: putting it together

    Eight questions that mix the whole lesson: the cinema program, compiler errors and one logic bug.

    Part 7 of 7

    Wrap-up

    What to remember, a final quiz, your homework and a look at the next lesson.

    // 7.1

    Key takeaways

    1. A condition is a boolean expression. A number is not a condition: if (count) doesn’t compile.

    2. if runs its block when the condition is true, else when it is false. Exactly one of the two runs.

    3. In an else if chain the first true condition wins and the rest are not checked. Put the most specific condition first.

    4. Always write braces. Without them an if controls one statement, an else binds to the nearest if, and a stray ; becomes the whole body.

    5. Compare Strings with .equals, write if (isActive) instead of == true, and never use = where you mean ==.

    6. ?: picks one of two values. It is an expression: use it where a value goes, not to run code.

    7. A classic switch falls through from case to case until a break. Arrow labels -> never fall through.

    8. A switch expression gives a value, must cover every input (usually with default) and uses yield inside a block.

    // 7.2

    Check yourself

    Twenty questions on the whole lesson. You see the answer right after you pick.

    Your score
    0 / 20
    Answer the questions above.

    Your checkpoints

    // 7.3

    Homework

    You don’t know how to read input from the keyboard yet, so put the input in variables at the top of main, run the program, change the values and run it again. Tick items as you finish them. Your ticks are saved in this browser only.

    0 of 7 done

    // 7.4

    Questions?

    Next lesson: Loops and Iteration. for, while and do-while repeat code, and break and continue steer a loop. You already know break from the switch.

    Lesson 05 preview
    for (int i = 1; i <= 5; i++) {
        System.out.println(i % 2 == 0 ? i + " is even" : i + " is odd");
    }
    $ java Main
    1 is odd
    2 is even
    3 is odd
    4 is even
    5 is odd