# AP® Computer Science A 2.5 Compound Boolean Expressions

Source: https://lockincs.com/ap-csa/unit-2/2-5-compound-boolean-expressions/  
Last reviewed against the College Board Course and Exam Description (CED): 2026-11-12  
CED codes: 2.5.A, 2.5.A.1, 2.5.A.2

The logical operators ! (not), && (and) and || (or) combine Boolean expressions into compound Boolean expressions that evaluate to a Boolean value. Java applies ! first, then &&, then ||. With short-circuit evaluation, when the first operand of && or || already decides the result, the second Boolean expression is not evaluated.

## What you will learn

- 2.5.A Develop code to represent compound Boolean expressions and determine the result of these expressions.

## 1\. The three logical operators

Logical operators are used with Boolean expressions 2.5.A.1. Each one produces a Boolean value.

-   `!a` (not) is true if `a` is false, and false otherwise.
-   `a && b` (and) is true if both `a` and `b` are true, and false otherwise.
-   `a || b` (or) is true if `a` is true, `b` is true, or both are true, and false otherwise.

A truth table lists every combination of inputs:

| a | b | !a | a && b | a || b |
| --- | --- | --- | --- | --- |
| true | true | false | true | true |
| true | false | false | false | true |
| false | true | true | false | true |
| false | false | true | false | false |

```
int age = 15;
boolean hasTicket = true;
System.out.println(age >= 13 && hasTicket);
System.out.println(age >= 18 || hasTicket);
System.out.println(!hasTicket);
```

Output:

```
true
true
false
```

An expression that uses logical operators evaluates to a Boolean value, so you can store it, print it or use it as an `if` condition 2.5.A.1.

## 2\. Order of precedence

When an expression mixes logical operators, Java evaluates `!` (not) first, then `&&` (and), then `||` (or) 2.5.A.1. Arithmetic and relational operators are evaluated before `&&` and `||`.

```
boolean a = true;
boolean b = false;
boolean c = false;
System.out.println(a || b && c);
System.out.println((a || b) && c);
System.out.println(!a || c);
```

Output:

```
true
false
false
```

Step by step for `a || b && c`: first `b && c` is `false && false`, which is `false`. Then `a || false` is `true || false`, which is `true`. Parentheses change the order: `(a || b) && c` is `true && false`, which is `false`.

**Watch out:** `!` binds very tightly. To negate a comparison, put the comparison in parentheses.

```
int x = 5;
boolean result = !x > 3;
```

```
error: bad operand type int for unary operator '!'
```

The fix is `!(x > 3)`.

## 3\. Ranges with && and ||

To check whether a value is inside a range, join two comparisons with `&&`. To check whether it is outside, use `||`.

```
int hour = 22;
boolean openHours = hour >= 9 && hour <= 17;
boolean quietHours = hour < 7 || hour > 21;
System.out.println("Open: " + openHours);
System.out.println("Quiet: " + quietHours);
```

Output:

```
Open: false
Quiet: true
```

**Watch out:** `hour < 7 && hour > 21` can never be true, because no number is both below 7 and above 21. This is a logic error: the code compiles, but the condition is always false.

## 4\. Short-circuit evaluation

Short-circuit evaluation: when the first Boolean expression alone already settles the result of `&&` or `||`, Java does not evaluate the second Boolean expression at all 2.5.A.2.

-   `false && anything` is always false, so Java skips `anything`.
-   `true || anything` is always true, so Java skips `anything`.

Programmers use this on purpose as a safety check. Here the division only happens when it is safe:

```
int games = 0;
int points = 40;
if (games != 0 && points / games > 10) {
    System.out.println("High scorer");
} else {
    System.out.println("Not enough data");
}
```

Output:

```
Not enough data
```

`games != 0` is false, so `points / games` is never evaluated. Swap the two sides and the division runs first:

```
int games = 0;
int points = 40;
if (points / games > 10 && games != 0) {
    System.out.println("High scorer");
}
```

Output:

```
Exception in thread "main" java.lang.ArithmeticException: / by zero
```

The same idea protects a method call on a reference that might be `null`:

```
String nickname = null;
if (nickname != null && nickname.length() > 3) {
    System.out.println("Long nickname");
} else {
    System.out.println("No long nickname");
}
```

Output:

```
No long nickname
```

## 5\. Short-circuit and side effects

If the second expression calls a method that does something visible, such as printing, short-circuit evaluation means that call may not happen. Exam questions use this to test whether you really know which side runs.

```
public class ShortCircuitDemo {
    public static boolean isLong(String word) {
        System.out.println("Checking " + word);
        return word.length() > 5;
    }

    public static void main(String[] args) {
        boolean first = 5 > 2 || isLong("banana");
        System.out.println("first: " + first);
        boolean second = 5 < 2 || isLong("kiwi");
        System.out.println("second: " + second);
    }
}
```

Output:

```
first: true
Checking kiwi
second: false
```

In `first`, the left side is true, so `isLong("banana")` is never called and nothing extra is printed. In `second`, the left side is false, so Java must evaluate the right side: `isLong("kiwi")` runs, prints its line and returns `false`.

## Common mix-ups

- Not true: || means one or the other, but not both. a || b is true when a is true, b is true, or both are true. It is false only when both are false.
- Not true: Java evaluates && and || from left to right with equal priority. && has higher precedence than ||, just as * is done before +. true || false && false is true, because false && false is evaluated first.
- Not true: Java always evaluates both sides of && and ||. Short-circuit evaluation skips the second expression when the first already decides the result: false for && and true for ||.

## In 30 seconds

- !a is true when a is false, and false when a is true.
- a && b is true only when both are true. a || b is true when at least one is true.
- Precedence: ! first, then &&, then ||. Arithmetic and relational operators come before && and ||.
- A compound Boolean expression evaluates to a single Boolean value.
- Short-circuit: false && ... and true || ... stop early, so the second expression is not evaluated.
- Write ranges with two comparisons: x >= 1 && x <= 10.

## Checkpoint: 5 practice questions

### Question 1

Consider the following code segment. What is printed as a result of executing the code segment?

```java
boolean p = true;
boolean q = false;
boolean r = true;
System.out.println((p || q && !r) + " " + ((p || q) && !r));
```

- A. true true
- B. false false
- C. true false
- D. false true

**Answer: C.** `!` is applied first, so `!r` is false. In `p || q && !r`, `&&` comes before `||`: `q && false` is false, then `true || false` is true. In `(p || q) && !r`, the parentheses go first: `true && false` is false. "false false" evaluates the first expression from left to right as if `||` came first.

### Question 2

Consider the following method and code segment, which appear in the same class. What is printed as a result of executing the code segment?

```java
public static boolean check(int n) {
    System.out.print("c" + n + " ");
    return n > 0;
}

// code segment
int x = 3;
if (x > 5 && check(1)) {
    x++;
}
if (x < 5 || check(2)) {
    x += 10;
}
System.out.println(x);
```

- A. 13
- B. c2 13
- C. c1 c2 13
- D. c1 3

**Answer: A.** In the first `if`, `x > 5` is false, so `&&` short-circuits and `check(1)` is never called; x stays 3. In the second `if`, `x < 5` is true, so `||` short-circuits and `check(2)` is never called either; x becomes 13. "c1 c2 13" assumes Java always evaluates both sides, and "c2 13" forgets that a true left operand also stops `||`.

### Question 3

The `int` variables `total` and `count` have been declared and initialized, and `count` may be 0. Which of the following Boolean expressions can never cause an `ArithmeticException`?

- A. `total / count > 5 && count != 0`
- B. `count != 0 || total / count > 5`
- C. `total / count > 5 || count != 0`
- D. `count != 0 && total / count > 5`

**Answer: D.** With `count != 0 && total / count > 5`, a count of 0 makes the first operand false, so short-circuit evaluation skips the division. Putting the division first divides by 0 before any check. With `count != 0 || ...`, a count of 0 makes the first operand false, so `||` must evaluate the division, which throws the exception.

### Question 4

A ride admits riders whose height `h` (an `int`, in centimeters) is from 120 to 190, inclusive. Which expression evaluates to `true` exactly when a rider is NOT allowed on the ride?

- A. `h < 120 && h > 190`
- B. `h < 120 || h > 190`
- C. `h <= 120 || h >= 190`
- D. `h > 120 && h < 190`

**Answer: B.** A rider is not allowed when the height is below 120 or above 190, and either one is enough, so the operator is `||`. `h < 120 && h > 190` can never be true, since no number is both. `h <= 120 || h >= 190` wrongly rejects riders of exactly 120 or 190, and the last option describes allowed riders (and even misses the boundaries).

### Question 5

The `boolean` variables `a` and `b` have been declared and initialized. Which of the following best describes when `a || b` evaluates to `true`?

- A. Only when exactly one of `a` and `b` is true, but not when both are true
- B. Only when both `a` and `b` are true
- C. When at least one of `a` and `b` is false
- D. When `a` is true, `b` is true, or both are true

**Answer: D.** `||` (or) is true if `a` is true, `b` is true, or both are true; it is false only when both are false. "Exactly one" is a common mistake from everyday English, but `true || true` is true. "Both true" describes `&&`.

## Questions students ask

**What are the logical operators in Java?**

! (not), && (and) and || (or). They work on Boolean values and produce a Boolean value.

**What is short-circuit evaluation in Java?**

When the first operand of && is false, or the first operand of || is true, the result is already known, so Java does not evaluate the second operand.

**Which is evaluated first, && or ||?**

&&. The order of precedence is ! (not), then && (and), then || (or). Use parentheses when you want a different order.

**How do I check if a number is between two values in Java?**

Use two comparisons joined by &&, for example x >= 1 && x <= 10. Java does not allow 1 <= x <= 10.

---

© LockInCS, licensed CC BY-NC-ND 4.0. AP® is a trademark registered by the College Board, which is not affiliated with, and does not endorse, this website.
