Unit 2 · 18 min

2.5 Compound Boolean Expressions

Logical operators combine true and false values, and Java stops evaluating as soon as the answer is known.

Summary, objectives and course and exam description (CED) codes

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.

By the end of this session you can

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

2.5.A2.5.A.12.5.A.2

Reviewed against the CED on

Know this already? Jump to the checkpoint.

1LearnThe notes, the traps and how to remember them

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.

Lock it in: memory hooks

  • &&AND is strict: everyone must say yes.
  • ||OR is easygoing: one yes is enough.
  • PrecedenceNot, And, Or: N-A-O, in that order, like * before +.
  • Short-circuitPut the safety check on the left: if it fails, the risky part never runs.

Common misconceptions

  • "|| means one or the other, but not both."

    Not quite. a || b is true when a is true, b is true, or both are true. It is false only when both are false.

  • "Java evaluates && and || from left to right with equal priority."

    Not quite. && has higher precedence than ||, just as * is done before +. true || false && false is true, because false && false is evaluated first.

  • "Java always evaluates both sides of && and ||."

    Not quite. Short-circuit evaluation skips the second expression when the first already decides the result: false for && and true for ||.

Exam traps

  • count != 0 && total / count > 5 is safe when count is 0. Swap the two sides and the division runs first, throwing an ArithmeticException.
  • x < 0 && x > 10 is never true. To test outside a range, use ||: x < 0 || x > 10.
  • true || false && false is true, not false: && is done before ||.
  • !x > 3 does not compile when x is an int. Write !(x > 3).
  • Short-circuit also skips anything the second expression would do, such as a method call that prints.

2PracticeRecall it, then check yourself

In 30 seconds

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

Cover this list, say the points out loud, then take the checkpoint without scrolling back up.

Checkpoint · 5 questions

Checkpoint: Compound Boolean Expressions

Pick an answer to mark it. Every answer is explained, and you can try any question again. Your saved score counts first tries only, and stays in this browser.

  1. 1 Consider the following code segment. What is printed as a result of executing the code segment? 2.5.A.1
    boolean p = true;
    boolean q = false;
    boolean r = true;
    System.out.println((p || q && !r) + " " + ((p || q) && !r));
    Show answer

    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.

  2. 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? 2.5.A.2
    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);
    Show answer

    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 ||.

  3. 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? 2.5.A.2
    Show answer

    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.

  4. 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? 2.5.A.1
    Show answer

    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).

  5. 5 The boolean variables a and b have been declared and initialized. Which of the following best describes when a || b evaluates to true? 2.5.A.1
    Show answer

    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 &&.

3PrevailLock it in for exam day

By the numbers

Name each list from memory, then reveal it to check. Each list shows how many items to recall.

  • Logical operators, in order of precedence three operators CED 2.5.A.1
    1. !not
    2. &&and
    3. ||or
  • Cases where short-circuit evaluation skips the second expression two cases CED 2.5.A.2
    1. && when the first expression is falseresult is false
    2. || when the first expression is trueresult is true

Key terms: flip the cards

Read the term, say the definition out loud, then flip to check. Struggling a little to remember is what makes it stick.

  • Logical operatorstap to flip

    The operators ! (not), && (and) and || (or), which combine Boolean expressions into a compound Boolean expression. Precedence: !, then &&, then ||.

    Example and CED codes
  • Short-circuit evaluationtap to flip

    When the first operand of && or || already decides the result, the second Boolean expression is not evaluated.

    Example and CED codes
  • Boolean expressiontap to flip

    An expression that evaluates to a Boolean value, true or false, such as a comparison with a relational operator or a combination with logical operators.

    Example and CED codes
  • Truth tabletap to flip

    A table that lists every combination of true and false for the variables in Boolean expressions, with the value of each expression in every row.

    Example and CED codes
  • Relational operatorstap to flip

    The operators ==, !=, <, >, <= and >=, which compare two values and evaluate to a Boolean value.

    Example and CED codes

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.

Was this page helpful?

No names are ever shown, and every public comment is checked by us first. Please do not include personal details. To get a reply, email [email protected].

↑ Top

Enlarged view of the selected figure