Operators & Control Flow

Course 1 · Ch 3
Operators & Control Flow
Mostly familiar territory from C/C++/Rust — until switch quietly gets a modern replacement

java1-2 covered the eight primitives and the reference/value split. This chapter puts them to work — most of it will feel immediately familiar coming from C, C++, or Rust, with two genuine exceptions worth slowing down for.

Standard Operators

Arithmetic (+ - * / %), relational (== != < > <= >=), logical (&& || !), and compound assignment (+= -= *= /=) all behave exactly as they do in C/C++. Nothing new to learn here — genuinely shared syntax across all four languages this site has covered.

Integer Division & the Common C-Style Trap

int result = 5 / 2; // 2, not 2.5 — truncated, exactly like C's own int/int division double correct = 5 / (double) 2; // 2.5 — an explicit cast forces floating-point division

Division between two int values truncates toward zero, exactly the same trap c1-3 covered for C. Java doesn't fix this — it's the same behavior, inherited from the same C-family lineage, and it requires the same explicit cast to force floating-point division.

Traditional switch — Fallthrough, the Same Footgun

switch (day) { case 1: case 2: System.out.println("Weekday"); break; // forget this and execution falls through into the next case case 6: System.out.println("Saturday"); break; }

Java's traditional switch falls through by default, identical to C's own switch statement covered in c1-3 — omitting break is a genuine, real bug class in both languages, not just a Java quirk.

Switch Expressions — Java's Real Fix

String result = switch (day) { case 1, 2, 3, 4, 5 -> "Weekday"; case 6, 7 -> "Weekend"; default -> { System.out.println("Invalid day"); yield "Unknown"; // yield produces the branch's value from a block } };

Java 14 introduced switch expressions: the arrow form (->) has no fallthrough at all — each branch is isolated — and the whole expression can produce a value directly, assigned straight into result. Multi-statement branches use a block with yield to supply the value.

Pattern Matching — A Light Touch

if (obj instanceof String s) { // s is already a String here — no separate explicit cast needed System.out.println(s.length()); }

Since Java 16, instanceof can bind the checked-and-cast value directly to a new variable in one step, removing the old two-step check-then-cast pattern. Java 21 extends this into switch itself, matching directly on an object's type. This course won't go deep on pattern matching — it's flagged here mainly so the syntax isn't a surprise when it appears in later chapters.

BehaviorC (c1-3)Java traditional switchJava switch expression
Fallthrough between casesyes, by defaultyes, by defaultno — never falls through
Produces a value directlynonoyes, via -> or yield
Multiple labels per branchstacked case labelsstacked case labelscomma-separated on one line
Prefer switch expressions for new code
The arrow form eliminates fallthrough entirely and reads as a direct value-producing expression — reach for it over the traditional statement form whenever the target Java version supports it (14+).
A missing break is the same real bug in Java as in C
Traditional switch fallthrough isn't a Java-specific gotcha — it's the identical bug class c1-3 covered for C's own switch, inherited unchanged. Missing one break silently executes the next case's body too.

Coding Challenges

Challenge 1

Write a program that divides 7 by 2 using int division, then again using an explicit cast to force floating-point division. Print both results and label which is truncated.

📄 View solution
Challenge 2

Write a traditional switch statement over an int month (1-12) that deliberately omits a break in one case to demonstrate fallthrough, then rewrite the same logic as a switch expression using the arrow form and show it no longer falls through.

📄 View solution
Challenge 3

Write a method that accepts an Object and uses instanceof pattern matching to print its length if it's a String, or its value doubled if it's an Integer, with no explicit cast in either branch.

📄 View solution

Chapter 3 Quick Reference

  • Arithmetic/relational/logical/compound-assignment operators are shared syntax with C/C++
  • int/int division truncates toward zero — identical to C's own behavior (c1-3), fixed the same way: cast one operand to double
  • Traditional switch falls through by default — the same real bug class as C's switch
  • Switch expressions (->) never fall through and can produce a value directly; yield supplies a value from a multi-statement block
  • instanceof pattern matching binds the cast value directly, removing the old check-then-cast two-step
  • Next chapter: classes, objects, and Java's four access levels