Conditional Statements
A robot with no conditionals can only do one thing. Conditionals are the decision layer — they let the robot ask "what state am I in?" and "what should I do right now?" Every intake toggle, every arm position limit, every autonomous mode selection runs through this logic fifty times a second.
By the end of this lesson, you will:
- Write correct
if,if-else, andif-else if-elsechains for multi-condition robot decisions - Explain why the order of conditions in a chain encodes a priority hierarchy
- Use
switchfor mode and state selection, including thebreakkeyword and fall-through behavior - Apply the ternary operator for concise, single-value conditional assignments
- Refactor deeply nested conditions into guard clauses for flatter, more readable robot code
- Identify the three most common conditional bugs: missing curly braces,
=vs==, and unguarded fall-through
Decisions in a 20ms Loop
Every 20 milliseconds, the periodic method runs from top to bottom. There are no pauses, no waiting — just code executing in sequence, fifty times a second. Conditional statements are how you encode the robot's decision logic into that sequence: given the current state of every input right now, what should each mechanism do?
That framing matters. In robot code, a conditional isn't "should I bring an umbrella?" — it's "given that the driver is holding the right bumper, the arm is above 45 degrees, and the beam break is clear, should the shooter wheel be spinning?" The conditions are physical. Getting the logic wrong moves hardware in the wrong direction.
The if — else if — else Ladder
Java evaluates an if-else if-else chain from top to bottom. The first condition that evaluates to true runs its block and the rest of the chain is skipped entirely. This makes ordering a design decision, not just a formatting choice — the most specific or highest-priority conditions go first.
The decision tree below models a real arm controller. Click any branch to trace which block runs and understand why its position in the chain matters.
Swapping the fault check and the score button means a faulted motor keeps moving as long as the driver holds a button. That isn't a code style preference — it's a safety decision written in ordering.
The Missing Curly Braces Bug
Java allows a single-statement if body without curly braces. This is one of the most reliably problematic features of the language. Without braces, only the very next statement belongs to the if. Every statement after it runs unconditionally — even if the indentation implies otherwise.
The missing-braces bug is invisible in a text editor because indentation makes it look conditional. On a robot, the consequence I see most often is runaway logging: a "fault detected" message floods the console on every 20ms cycle regardless of whether there's an actual fault, and real faults become impossible to spot in the noise. Team 2910's style rule is absolute: curly braces on every block, always. Some teams configure their linter to enforce it automatically so nobody has to think about it.
The switch Statement
When you're selecting behavior based on a single variable matching one of several specific values — a mode integer, a state enum, a string label — switch is often cleaner than a long else if ladder. It jumps directly to the matching case instead of evaluating conditions from top to bottom.
The detail that trips people up every season: the break keyword is mandatory unless you specifically intend fall-through. Without it, execution continues into the next case's code automatically, with no warning from the compiler.
Each case ends with break, so execution exits the switch block after the matching case runs. This is the pattern you want the vast majority of the time.
The default case is your safety net. A driver could accidentally select an out-of-range option on the dashboard. Without a default, nothing happens — the robot sits still at the start of autonomous. With a default that runs the simplest, safest auto routine, the robot at least moves.
Without break, execution falls through into the next case — running its code even though the value didn't match that case. The compiler does not warn you. The robot just does three things at once.
All three auto routines attempt to run in sequence. Depending on what they do, this could initialize conflicting hardware states, send contradictory motor commands, or cause a loop overrun. The robot doesn't throw an error — it just behaves inexplicably until you think to search for a missing break.
Fall-through is occasionally intentional — when multiple cases should trigger identical behavior. The distinction from the bug: intentional fall-through has no code between the stacked cases, making the intent visually unambiguous.
Use switch when you're comparing one variable against multiple constant values — a mode integer, a state enum, a string label from a chooser. Use if-else if when conditions involve ranges, multiple variables, or complex expressions like currentAmps > MAX_AMPS || hasFault(). A switch can only match equality. In Unit 5 you'll build state machines almost entirely on switch statements with enum values — that's the natural home of this construct.
The Ternary Operator
The ternary operator (? :) is a compact form of if-else that produces a value. It's not a conditional block — it's an expression that evaluates to one of two options based on a condition. Use it for simple single-value assignments where both branches fit cleanly on one line.
When not to use it
The ternary is a one-condition, one-value tool. Nesting ternaries to handle three or more cases produces code that nobody can parse under pressure:
Guard Clauses: Keeping Conditions Readable
Deeply nested if statements are common in robot code and make it hard to trace what actually runs under which conditions. The fix is the guard clause: check for failure cases first with an early return, then let the main logic run at the top level of indentation.
Both versions behave identically. The guard clause version has four explicit preconditions, each with a safe fallback action. Adding a new precondition next week — a "gyro calibrated" check, a "battery above 11V" check — slots in as one more guard clause without restructuring the whole method.
At a regional, I watched a team spend half of their lunch break debugging a shooter that wouldn't fire on certain driver inputs. Their method had five levels of nesting. The bug was a missing ! on a boolean buried in the third level — a condition that was supposed to check "is the intake not running" but instead checked "is the intake running." The guard-clause refactor took about ten minutes and made the missing inversion immediately obvious. Shallow code is a debugging speed multiplier, and debugging speed matters most when you have the least time.
Revisiting = vs. == in a Conditional
Lesson 3 introduced this as an operator distinction. Here it is in the conditional context where it actually causes robot bugs. It's worth repeating because it appears at every experience level, and with a boolean on the left side, the Java compiler's warning is easily missed.
The best prevention is the last pattern: when a variable is boolean, use it directly as the condition. if (intakeRunning) can never be confused with an assignment. if (intakeRunning == true) opens the door for the one-character typo that changes the whole meaning.
🔌 System Check
Each of these has caused a real robot to do the wrong thing at a real competition.
- Safety conditions must be first in every chain. Any condition that cuts motor power on a fault or overcurrent event must be the first
if, not anelse ifburied after game logic. If a fault check is downstream of a driver command, an active driver input can prevent the safety from triggering. - Every if block gets curly braces — always. No exceptions for "simple" single-statement bodies. Lint rules can enforce this automatically; configure them at the start of the season and don't disable them.
- Every switch case gets a break — or a comment explaining why it doesn't. An unexplained missing
breakis always treated as a bug during code review. If fall-through is intentional, document it. - Every switch gets a default case. Hardware selection on a dashboard, auto chooser, or mode selector can produce unexpected values. A
defaultthat runs your safest fallback behavior is the difference between "wrong auto routine" and "robot sits still in autonomous." - Boolean conditions should use the variable directly.
if (limitSwitch), notif (limitSwitch == true). The shorter form eliminates the assignment-typo class of bug entirely. - Flatten nested conditions before code review. If any method in your robot code has more than three levels of indentation, it's a guard clause refactor waiting to happen. Deeply nested safety logic is harder to audit and easier to break on maintenance.
Knowledge Check
Click an answer to check your understanding.
break in case 1 of a switch on autoMode. The robot is set to autoMode = 1 before the match. What runs during autonomous?if statements that eventually calls motor.set(speed). A teammate refactors it using guard clauses. Which statement correctly describes what changes?Rewrite and Reason
The following method works — sort of. It controls a climber mechanism but has four distinct conditional problems. Find them, explain what could go wrong on the robot for each one, and produce a corrected version.
- Identify all four problems. For each one, write one sentence describing what it does to the robot's physical behavior — not just what the syntax error is.
- Rewrite the method using guard clauses, corrected syntax, and curly braces on every block. Add a comment to each guard clause explaining what physical condition it is protecting against.
- The current method uses four separate
ifstatements rather than anif-else ifchain. Explain why this is a problem: what happens ifclimbButtonis held andhasFault()returnstrueat the same time? How does your rewrite prevent this? - Bonus: Add a
switchstatement to handle three climber modes —EXTEND,RETRACT, andHOLD— selected from an enum. TheHOLDcase should share the same behavior as a futureBRAKEcase using intentional fall-through. Add a comment documenting the fall-through intent.