AP Computer Science A Boolean Expressions and if Statements — Worked Answer Explanations

Unit 3 · 12 questions explained

Below is a complete answer key for our AP Computer Science A Boolean Expressions and if Statements practice questions. For each question you'll find the correct choice, a full written explanation of how to get there, and — for every wrong answer — a short note on exactly why it's tempting and where it goes wrong. Reading these straight through is one of the fastest ways to find the gaps in a unit before exam day.

Prefer to test yourself first? Take the timed Boolean Expressions and if Statements practice test and come back here to review, or head back to the Boolean Expressions and if Statements unit overview.

In-content ad
  1. Question 1 · Easy

    What is the output of the following code?

    int x = 5;
    if (x > 3) {
        System.out.println("A");
    } else if (x > 4) {
        System.out.println("B");
    } else {
        System.out.println("C");
    }
    
    • A
      ACorrect
    • B
      B
      Why not B: The first condition x > 3 is true (5 > 3). In an if-else chain, once a true branch is found, the rest are skipped — "B" is never reached.
    • C
      A\nB
      Why not C: An if-else if-else chain executes at most one branch. Both conditions are true but only the first matching branch executes.
    • D
      C
      Why not D: The else branch only runs when all preceding conditions are false. Here, x > 3 is true, so "A" is printed.
    Explanation

    In an if-else if-else chain, conditions are checked in order and only the first true branch executes. x > 3 (5 > 3) is true, so "A" is printed and the rest of the chain is skipped, even though x > 4 is also true.

    Key takeaway

    In an if-else if chain, only the FIRST true condition's branch executes — the rest are skipped.

  2. Question 2 · Easy

    Which boolean expression correctly checks whether x is between 1 and 10 (inclusive)?

    • A
      1 <= x <= 10
      Why not A: This is not valid Java. Java does not support chained comparisons. This would cause a compile error.
    • B
      x >= 1 && x <= 10Correct
    • C
      x >= 1 || x <= 10
      Why not C: Using || makes this true for almost every integer (e.g., x = 100 satisfies x >= 1). Use && for a range check.
    • D
      !(x < 1 && x > 10)
      Why not D: De Morgan's applied correctly would give !(x < 1) || !(x > 10) = x >= 1 || x <= 10, which is not a range check.
    Explanation

    A range check requires BOTH conditions to be true simultaneously: x >= 1 AND x <= 10. Use && (logical AND). Option A is not valid Java syntax. Option C with || is true for most values, not just 1–10.

    Key takeaway

    Range checks use `&&`: both bounds must be satisfied. `1 <= x <= 10` is not valid Java — write `x >= 1 && x <= 10`.

  3. Question 3 · Easy

    What is the output of the following code?

    boolean a = true;
    boolean b = false;
    System.out.println(!a || b);
    System.out.println(!(a || b));
    
    • A
      false\nfalseCorrect
    • B
      true\nfalse
      Why not B: !a = !true = false; false || b = false || false = false. First line is false, not true.
    • C
      false\ntrue
      Why not C: a || b = true || false = true; !(true) = false. Second line is false, not true.
    • D
      true\ntrue
      Why not D: Both expressions evaluate to false: (!true || false) = false; !(true || false) = !true = false.
    Explanation

    Line 1: !a || b = !true || false = false || false = false. Line 2: !(a || b) = !(true || false) = !(true) = false. The ! operator has higher precedence than || in line 1, but the parentheses in line 2 force || first.

    Key takeaway

    `!` has higher precedence than `||` and `&&`. Use parentheses to control evaluation order with logical operators.

  4. Question 4 · Easy

    What is the output of the following code?

    int score = 85;
    String grade;
    if (score >= 90) {
        grade = "A";
    } else if (score >= 80) {
        grade = "B";
    } else if (score >= 70) {
        grade = "C";
    } else {
        grade = "F";
    }
    System.out.println(grade);
    
    • A
      A
      Why not A: 85 < 90, so the first condition is false. The code checks the next condition.
    • B
      BCorrect
    • C
      C
      Why not C: 85 >= 80 is true, so "B" is assigned and the remaining conditions are skipped. The code never reaches the C branch.
    • D
      F
      Why not D: The else branch is only reached if all previous conditions are false. 85 >= 80 is true, so F is not assigned.
    Explanation

    85 < 90 (first branch false) → 85 >= 80 (true) → grade = "B". Once a true branch is found, the remaining else-if and else branches are skipped.

    Key takeaway

    Cascading if-else if chains match the first true condition and skip the rest — order matters.

  5. Question 5 · Easy

    Which of the following best demonstrates short-circuit evaluation of &&?

    String s = null;
    if (s != null && s.length() > 0) {
        System.out.println("Non-empty");
    } else {
        System.out.println("Null or empty");
    }
    
    • A
      NullPointerException is thrown.
      Why not A: Short-circuit evaluation means s.length() > 0 is NOT evaluated when s != null is false. So no NPE occurs.
    • B
      "Null or empty" is printed.Correct
    • C
      "Non-empty" is printed.
      Why not C: s is null, so s != null is false. With &&, false AND anything = false, so the else branch executes.
    • D
      Compile error: cannot call length() on potentially null reference.
      Why not D: Java does not check for null safety at compile time this way. The code compiles fine; the runtime protection is provided by short-circuit evaluation.
    Explanation

    && short-circuits: if the left operand is false, the right operand is not evaluated. Since s is null, s != null is false, so s.length() > 0 is never executed (no NPE). The else branch prints "Null or empty".

    Key takeaway

    `&&` short-circuits on false: the right side is skipped if the left is false. This safely guards against NullPointerException.

  6. Question 6 · Easy

    What is the output of the following code?

    int x = 4;
    if (x % 2 == 0)
        System.out.println("even");
        System.out.println("positive");
    
    • A
      even
      Why not A: Without braces, only the immediately following statement (println("even")) is the if body. The second println is always executed.
    • B
      even\npositiveCorrect
    • C
      positive
      Why not C: Both prints execute: the first because the condition is true, the second because it is outside the if body (no braces).
    • D
      Compile error
      Why not D: This is valid Java. Without braces, only the first statement after the if is the conditional body.
    Explanation

    Without curly braces, an if statement controls only the single statement immediately following it. println("even") is inside the if (condition is true, so it runs). println("positive") is NOT inside the if — it always runs regardless of the condition.

    Key takeaway

    Without braces, only the ONE statement immediately after `if` is conditional. Always use braces to avoid this pitfall.

  7. Question 7 · Easy

    Which expression is equivalent to !(a && b) according to De Morgan's Law?

    • A
      !a && !b
      Why not A: De Morgan's Law: NOT (A AND B) = (NOT A) OR (NOT B). The operator changes from AND to OR.
    • B
      !a || !bCorrect
    • C
      a || b
      Why not C: De Morgan's requires negating both operands AND flipping the operator. a || b is missing the negations.
    • D
      !(a) && !(b)
      Why not D: This is !a && !b, which equals !(a || b) by De Morgan's, not !(a && b).
    Explanation

    De Morgan's Laws: !(a && b) = !a || !b and !(a || b) = !a && !b. When distributing NOT over AND/OR, negate both operands AND flip the logical operator (AND becomes OR, OR becomes AND).

    Key takeaway

    De Morgan's Laws: `!(a && b)` = `!a || !b`; `!(a || b)` = `!a && !b`. The operator flips when NOT is distributed.

  8. Question 8 · Easy

    What does the following code print?

    int a = 5;
    int b = 5;
    System.out.println(a == b);
    String s1 = new String("hello");
    String s2 = new String("hello");
    System.out.println(s1 == s2);
    System.out.println(s1.equals(s2));
    
    • A
      true\ntrue\ntrue
      Why not A: new String("hello") explicitly creates a new object. s1 == s2 compares references: two different objects, so false.
    • B
      true\nfalse\ntrueCorrect
    • C
      true\nfalse\nfalse
      Why not C: s1.equals(s2) compares content, not references. Both contain "hello", so equals() returns true.
    • D
      false\nfalse\ntrue
      Why not D: a == b on primitives compares values: 5 == 5 is true. The == issue only applies to objects, not primitives.
    Explanation

    For primitives, == compares values: 5 == 5 → true. new String("hello") creates a new heap object each time, so s1 == s2 compares different references → false. .equals() compares character content → true.

    Key takeaway

    For primitives, `==` compares values. For objects, `==` compares references; use `.equals()` for content comparison.

  9. Question 9 · Easy

    What is the output of the following code?

    boolean x = true;
    boolean y = false;
    if (x || y) {
        System.out.print("1 ");
    }
    if (x && y) {
        System.out.print("2 ");
    }
    if (!y) {
        System.out.print("3 ");
    }
    
    • A
      1 3Correct
    • B
      1 2 3
      Why not B: x && y = true && false = false, so "2 " is not printed.
    • C
      1 2
      Why not C: !y = !false = true, so "3 " IS printed. Also x && y is false so "2 " is NOT printed.
    • D
      3
      Why not D: x || y = true || false = true, so "1 " IS also printed.
    Explanation

    Each if is independent (no else). Evaluate: x || y = true → prints "1 ". x && y = false → skips "2 ". !y = !false = true → prints "3 ". Output is "1 3 " (with trailing space).

    Key takeaway

    Independent `if` statements all evaluate; only `if-else if` chains skip after the first match.

  10. Question 10 · Medium

    What is the output of the following code?

    int x = 10;
    if (x++ > 10) {
        System.out.println("greater");
    } else {
        System.out.println("not greater");
    }
    System.out.println(x);
    
    • A
      greater\n11
      Why not A: Post-increment uses the value BEFORE incrementing in the comparison. x++ compares 10 > 10 which is false.
    • B
      not greater\n11Correct
    • C
      not greater\n10
      Why not C: x++ does increment x; after the statement, x is 11. The increment happens even though the post-increment value was used in the condition.
    • D
      greater\n10
      Why not D: Post-increment x++ uses the original value (10) in the comparison, so 10 > 10 is false. And x does get incremented to 11.
    Explanation

    x++ in a condition uses the current value (10) for the comparison, then increments. So 10 > 10 is false → "not greater" prints. After the if statement, x has been incremented to 11.

    Key takeaway

    Post-increment (`x++`) returns the ORIGINAL value for the expression, then increments. The increment still happens even inside conditions.

  11. Question 11 · Medium

    What is the output of the following code?

    int x = 0;
    if (x = 5) {
        System.out.println("hello");
    }
    
    • A
      hello
      Why not A: The code does not compile. x = 5 is an assignment returning int, and an int cannot be used as a boolean condition in Java.
    • B
      Nothing is printed.
      Why not B: The code has a compile error; it never runs. (Unlike C/C++, Java requires a boolean expression in an if condition.)
    • C
      Compile error: incompatible types.Correct
    • D
      Runtime exception.
      Why not D: This is a compile-time error, not a runtime error. Java requires the if condition to be a boolean expression.
    Explanation

    In Java, the expression in an if condition must be of type boolean. x = 5 is an assignment expression of type int. Java does not allow an int where a boolean is expected, so this is a compile error. (This differs from C/C++ where this compiles.)

    Key takeaway

    Java requires a boolean expression in `if` conditions. Using `=` (assignment) instead of `==` causes a compile error when the type is not boolean.

  12. Question 12 · Medium

    What is the output of the following code?

    int a = 3;
    int b = 7;
    if (a > 0 && ++b > 7) {
        System.out.println("yes");
    } else {
        System.out.println("no");
    }
    System.out.println(b);
    
    • A
      yes\n8Correct
    • B
      no\n8
      Why not B: a > 0 is true (3 > 0), so the right side ++b > 7 IS evaluated. ++b makes b=8, and 8 > 7 is true, so the whole condition is true.
    • C
      yes\n7
      Why not C: ++b (pre-increment) increments b before the comparison. Since both sides are evaluated, b becomes 8.
    • D
      no\n7
      Why not D: a > 0 is true, so && does NOT short-circuit. ++b > 7 is evaluated: b becomes 8 and 8 > 7 is true. The condition is true.
    Explanation

    a > 0 is true (3 > 0). Since && short-circuits only on false, the right side is evaluated: ++b pre-increments b to 8, then 8 > 7 is true. The entire condition is true → "yes" prints. b is now 8.

    Key takeaway

    `&&` short-circuits only when the LEFT side is false. When left is true, the right side is always evaluated (and side effects like `++b` happen).