skip to content

What are Java's logical operators &&, ||, and !, and what does each do?

level: juniorimportance: must knowfreq 70%

answer

  1. && = AND (both true), || = OR (one true), ! = NOT (flip)
  2. Operands must be boolean — no truthy numbers in Java
  3. Precedence: ! > && > || ; add parens when mixing
  4. Used in if/while/for/ternary conditions

basics

~20 s

&& is logical AND: true only if both sides are true. || is logical OR: true if at least one side is true. ! is NOT: it flips a boolean, turning true into false and false into true.

solid answer

~40 s

Java has three core logical operators that work on boolean values and produce a boolean result. && (AND) returns true only when both operands are true. || (OR) returns true when at least one operand is true. ! (NOT) is unary and inverts a single boolean. They are most often used in conditions for if, while, and for. && and || are 'short-circuiting': they evaluate the left side first and skip the right side when the result is already determined (false && x stops at false; true || x stops at true). This matters because the skipped expression's side effects, like a method call, never run. Precedence is ! highest, then &&, then ||, so a || b && c means a || (b && c); use parentheses for clarity.

code

java · 13 lines
java
boolean loggedIn = true;
boolean admin = false;

if (loggedIn && admin) {
    System.out.println("Show admin panel");   // skipped: admin is false
}
if (loggedIn || admin) {
    System.out.println("Show dashboard");      // runs: loggedIn is true
}
System.out.println(!admin);                    // true (not admin)

// precedence: parsed as loggedIn || (admin && loggedIn)
boolean result = loggedIn || admin && loggedIn; // true

go deeper

for a junior

Can state the truth-table behavior of &&, ||, ! and use them in if conditions; knows operands must be boolean.

for a middle

Knows precedence (! > && > ||) and reaches for parentheses to keep conditions readable; understands short-circuiting exists.

for a senior

Articulates why Java rejects truthy numbers, designs conditions ordering cheap/likely-decisive checks first, and avoids subtle precedence bugs.

for a principal

Sets team conventions on condition readability, guards against precedence/NPE pitfalls in code review, and weighs expressiveness vs. clarity in shared utilities.

## What a boolean is In Java a **boolean** is a value that is either `true` or `false` — the two possible answers to a yes/no question. A **boolean expression** is any expression whose result is a boolean, e.g. `age >= 18` or `name.isEmpty()`. ## The three logical operators Logical operators combine or flip boolean values to make a new boolean. Java has three: - **`&&` — logical AND.** Result is `true` only if **both** the left and right operands are `true`; otherwise `false`. Read it as "and". Example: `isLoggedIn && hasPermission` is true only when the user is both logged in *and* has permission. - **`||` — logical OR.** Result is `true` if **at least one** operand is `true`; it is `false` only when both are false. Read it as "or". Example: `isAdmin || isOwner` is true when the user is an admin *or* the owner (or both). - **`!` — logical NOT.** This is **unary** (takes one operand). It **inverts** the boolean: `!true` is `false`, `!false` is `true`. Example: `!isEmpty` means "is not empty". ## Truth tables A truth table lists every combination of inputs and the output. ``` A B A && B A || B false false false false false true false true true false false true true true true true A !A false true true false ``` ## Where they are used Mostly inside conditions: `if (a && b) { ... }`, `while (running && !cancelled) { ... }`. The condition of `if`/`while`/`for` and the `? :` ternary all require a boolean, which logical operators produce. ## Short-circuiting (preview) `&&` and `||` are **short-circuiting**: they evaluate the left operand first and only evaluate the right operand if needed. For `&&`, if the left is `false` the whole thing is already `false`, so the right is skipped. For `||`, if the left is `true` the whole thing is already `true`, so the right is skipped. This is covered in depth in a separate question, but the key consequence is that any side effects in the skipped operand (like a method call or assignment) do not happen. ## Precedence and associativity When operators mix without parentheses, **precedence** decides who binds first. Among the logical operators: `!` is highest, then `&&`, then `||` is lowest. So `a || b && c` means `a || (b && c)`, and `!a && b` means `(!a) && b`. Comparison operators like `==`, `<`, `>` bind tighter than `&&`/`||`, so `x > 0 && y > 0` works without inner parentheses. When in doubt, **add parentheses** — they cost nothing and prevent bugs. ## Operands must be boolean Unlike C, Java does not treat numbers as truthy/falsy. `if (5)` does not compile; `if (count != 0)` does. The operands of `&&`, `||`, `!` must be of type `boolean` (or `Boolean`, which auto-unboxes).

  • Why does if (5) not compile in Java but does in C?
    Java requires boolean conditions; it does not coerce numbers to booleans. You must write an explicit comparison like if (count != 0).
  • What does a || b && c evaluate as, with parentheses?
    a || (b && c), because && has higher precedence than ||.

Think of a nightclub door. && is a two-bouncer gate: you pass only if BOTH bouncers wave you in. || is two doors: you get in through EITHER. ! is a sign that reverses a rule: 'NOT on the list' lets you in only when you're absent from it.

saying these in an interview costs you the question

  • Saying numbers can stand in for booleans (truthy/falsy) — false in Java
  • Claiming || has the same or higher precedence than && — it is lower
  • Confusing ! (logical NOT on boolean) with ~ (bitwise complement on integers)

context