Lesson 2.3: if Statements
Lesson 2.3: if Statements
Key Vocabulary
| Term | Definition |
|---|---|
| selection statement | A control structure that changes sequential flow by choosing which block to execute based on a boolean condition. In Java: if and if-else. (EK 2.3.A.1) |
| one-way selection | An if without an else. Body executes only when condition is true; 0 or 1 branches run. Code after the block always runs. (EK 2.3.A.3) |
| two-way selection | An if-else statement. Exactly one branch always executes — never both, never neither. (EK 2.3.A.4) |
| boolean expression | The condition inside the if parentheses. Must evaluate to true or false. A non-boolean here is a compile error. (EK 2.3.A.2) |
| block statement | Statements enclosed in { } treated as a single unit. Without braces, only the single immediately-following statement belongs to the if. |
| dangling else | Java always pairs else with the nearest unmatched if above it, regardless of indentation. Braces eliminate the ambiguity. |
| sequential execution | Default program flow: statements run top to bottom. Selection statements are the primary mechanism that breaks this linear flow. (EK 2.3.A.1) |
How Selection Fits Into Program Flow
By default Java executes statements sequentially. Selection statements break this linear flow by routing execution down one path based on a boolean condition. The core AP exam insight: code after the entire if or if-else block always runs regardless of which branch executed.
CED Connection (EK 2.3.A.1 & 2.3.A.2)
"Selection statements change the sequential execution of statements." and "An if statement affects the flow of control by executing different segments of code based on the value of a Boolean expression." Every AP exam question on 2.3 tests one of these two ideas.
One-Way Selection: the if Statement (EK 2.3.A.3)
A one-way selection provides a segment of code that runs only under a specific condition. If the condition is false, the body is entirely skipped and execution jumps to the first statement after the closing brace.
Syntax
if (booleanExpression) {
// body: executes only when booleanExpression is true
}
// always executes after the if block, true or false
Component roles
| Component | Role & AP Trap |
|---|---|
| if | Keyword that starts the statement. ⚠ If or IF is a compile error — keywords are case-sensitive.
|
| (condition) | Boolean expression evaluated each time this statement is reached. ⚠ if (n) with an int is a compile error in Java (unlike C/C++).
|
| { body } | Block that runs only when the condition is true. ⚠ No braces: only the single next statement belongs to the if. |
| after block | Runs unconditionally after the if, regardless of the condition. ⚠ Thinking it only runs when condition is false is the #1 trace error. |
Worked Example — Trace with Two Values
int temp = 95;
if (temp > 90) {
System.out.println("Heat advisory"); // line A
}
System.out.println("Check complete"); // line B
temp=95: true → A runs → B runs. Output: Heat advisory then Check complete.
temp=70: false → A skipped → B runs. Output: Check complete only. Line B always runs.
AP Trap: Missing Braces
Without braces only the single immediately-following statement belongs to the if. Indentation is irrelevant to Java. With x=3 below, B and C always print:
if (x > 5)
System.out.println("A"); // only this inside the if
System.out.println("B"); // ALWAYS runs
System.out.println("C"); // ALWAYS runs
Two-Way Selection: the if-else Statement (EK 2.3.A.4)
A two-way selection provides two code paths — exactly one always executes. There is no outcome where neither branch runs, and no outcome where both branches run.
Syntax
if (booleanExpression) {
// if-body: executes when condition is true
} else {
// else-body: executes when condition is false
}
// continues here after exactly one branch ran
Worked Example — Two ifs vs. if-else
// if-else: exactly one branch, always safe for mutual exclusion
int score = 55;
if (score >= 60) {
System.out.println("Pass");
} else {
System.out.println("Fail");
}
// Two separate ifs: breaks when first branch modifies tested state
int grade = 50;
if (grade < 60) { grade = 60; } // changes grade!
if (grade < 60) { // now always false
System.out.println("Fail"); // never prints
}
Use if-else for mutually exclusive outcomes. Separate ifs are fragile when the first modifies state that the second tests.
One-way vs. two-way comparison
| Property |
if only | if-else
|
|---|---|
| Branches that run | 0 or 1 | Exactly 1 |
| Condition false | Nothing extra runs | else-body runs |
| Use when | Action only when true | Two mutually exclusive outcomes |
AP Trap: Dangling else
Java pairs each else with the nearest unmatched if, not based on indentation. Always use braces in nested structures to make pairing explicit.
AP Trap: Assignment vs. Equality
if (score = 90) is a compile error — = returns an int, not a boolean. Use == to test equality.
AP Trap: Semicolon After the Condition
if (score >= 60); creates an empty body. The block that follows always executes regardless of the condition. Compiles without error but produces wrong behavior.
Real-World Connection
Selection is the decision engine of every program. A streaming service checks if you have a subscription before playing content. A thermostat checks if temperature is below the setpoint before turning on heat. AP FRQ problems require selection logic inside methods — precise understanding of one-way vs. two-way behavior is what separates a 4 from a 5.
Summary
-
One-way selection (
if): 0 or 1 branches execute. Code after the block always runs. (EK 2.3.A.3) -
Two-way selection (
if-else): exactly one branch always executes — never both, never neither. (EK 2.3.A.4) -
Braces essential: without them only the single following statement belongs to the
if. -
Dangling else: Java pairs
elsewith nearest unmatchedif. Use braces to prevent ambiguity. - Boolean expressions only: non-booleans in the condition cause a compile error. (EK 2.3.A.2)
-
Use
if-elsefor mutually exclusive outcomes, especially when the first branch modifies state.
Practice Questions
int x = 8;
if (x > 5) {
System.out.println("High");
}
System.out.println("Done");
HighDone
Done
High
8 > 5 is true, so High prints. Then execution continues past the if block and Done prints.int n = 3;
if (n > 10) {
System.out.println("Big");
}
System.out.println("End");
BigEnd
End
Big
3 > 10 is false, so the if body is skipped. End always prints because it’s outside the block.int score = 55;
if (score >= 60) {
System.out.println("Pass");
} else {
System.out.println("Fail");
}
Pass
PassFail
Fail
55 >= 60 is false, so the else branch executes and prints Fail. In an if-else, exactly one branch always runs.if-else) statement?else body runs when the boolean expression is false
if body and else body can execute for the same inputif body runs when the boolean expression is true
if-else, only one branch can execute for any given input — either the if body or the else body, never both. A, B, and D are all true statements.val = 0?int val = 0;
if (val > 0) {
System.out.println("Positive");
} else {
System.out.println("Not positive");
}
System.out.println("Checked");
PositiveChecked
Not positiveChecked
PositiveNot positiveChecked
Checked
0 > 0 is false, so Not positive prints. Then Checked always prints after the if-else. Note: 0 is not positive, so the else is correct here.x = 3?int x = 3;
if (x > 5)
System.out.println("A");
System.out.println("B");
System.out.println("C");
BC
C
ABC
AC
System.out.println("A") belongs to the if. Since 3 > 5 is false, A is skipped. But B and C are outside the if block and always execute.int age = 17;
if (age >= 18) {
System.out.println("Adult");
} else {
System.out.println("Minor");
}
if (age >= 16) {
System.out.println("Can drive");
}
AdultCan drive
Minor
AdultMinorCan drive
MinorCan drive
if-else: 17 >= 18 is false, so Minor prints. Second if: 17 >= 16 is true, so Can drive prints. These are two independent if statements.if (n / 2 == 0) {
System.out.println("Even");
} else {
System.out.println("Odd");
}
if (n == 2) {
System.out.println("Even");
} else {
System.out.println("Odd");
}
if (n % 2 == 0) {
System.out.println("Even");
} else {
System.out.println("Odd");
}
if (n % 2) {
System.out.println("Even");
} else {
System.out.println("Odd");
}
% checks divisibility. n % 2 == 0 is true when n has no remainder when divided by 2. A uses n / 2 == 0 which is only true when n is 0 or 1. B only checks if n equals 2. D puts an int in the condition (compile error — Java requires a boolean).Mastery: Trace Complex if Statements
int a = 10;
int b = 20;
if (a > b) {
System.out.println("A wins");
} else {
System.out.println("B wins");
}
if (a + b > 25) {
System.out.println("Sum is large");
}
A winsSum is large
B winsSum is large
B wins
A wins
10 > 20 is false → B wins. Second: 10 + 20 = 30 > 25 is true → Sum is large.x = 5?int x = 5;
if (x > 3) {
System.out.println("A");
if (x > 7) {
System.out.println("B");
}
System.out.println("C");
}
System.out.println("D");
ABCD
D
AD
ACD
5 > 3 is true → outer block runs, prints A. Inner: 5 > 7 is false → B is skipped. Outer continues: prints C. Finally D always prints.Zero only when n equals 0, and Nonzero otherwise. Which version has a logic error?Version 1:
if (n == 0) {
System.out.println("Zero");
} else {
System.out.println("Nonzero");
}
Version 2:if (n != 0) {
System.out.println("Nonzero");
} else {
System.out.println("Zero");
}
Version 3:if (n > 0) {
System.out.println("Nonzero");
} else {
System.out.println("Zero");
}
n > 0 (false), so it prints Zero — but -5 is not zero! Versions 1 and 2 both correctly print Nonzero when n = -5. n > 0 misses negative numbers.int m = 12;
if (m % 3 == 0) {
System.out.println("Divisible by 3");
}
if (m % 4 == 0) {
System.out.println("Divisible by 4");
}
if (m % 5 == 0) {
System.out.println("Divisible by 5");
}
Divisible by 3
Divisible by 3Divisible by 4Divisible by 5
Divisible by 3Divisible by 4
Divisible by 4
if statements, all checked. 12 % 3 = 0 → prints. 12 % 4 = 0 → prints. 12 % 5 = 2 → does not print. Key: these are separate ifs, not if-else, so multiple can execute.One-Way vs Two-Way: When Does It Matter?
A one-way if can technically do anything a two-way if-else can (by writing the else logic after the block). But there’s a case where a one-way if cannot fully replace an if-else without introducing bugs. Can you construct an example where removing the else and placing the code after the block changes the program’s behavior?
Get in Touch
Whether you're a student, parent, or teacher — I'd love to hear from you.
Just want free AP CS resources?
Enter your email below and check the subscribe box — no message needed. Students get daily practice questions and study tips. Teachers get curriculum resources and teaching strategies.
Message Sent!
Thanks for reaching out. I'll get back to you within 24 hours.
Prefer email? Reach me directly at [email protected]