Logical Operators in Java
Logical operators in Java work on operands of type boolean and produce a boolean result — true or false. They are the building blocks of compound conditions for the if statement and loops: AND (&, &&), OR (|, ||), exclusive OR (^), and NOT (!).
Logical Operators at a Glance
The following table lists the logical operators available in Java:
| Operator | Description | Example |
|---|---|---|
| & | Logical AND (AND), conjunction | true & false → false |
| | | Logical OR (OR), disjunction | true | false → true |
| ^ | Exclusive OR (XOR) | true ^ true → false |
| ! | Unary NOT (NOT), inversion | !true → false |
| && | Short-circuit AND (conditional-and) | false && x → false, x is not evaluated |
| || | Short-circuit OR (conditional-or) | true || x → true, x is not evaluated |
| == | Equality check | true == false → false |
| != | Inequality check | true != false → true |
| &= | AND with assignment | a &= b ≡ a = a & b |
| |= | OR with assignment | a |= b ≡ a = a | b |
| ^= | XOR with assignment | a ^= b ≡ a = a ^ b |
The precedence of the logical operators, from highest to lowest, is: !, then &, ^, |, &&, and finally ||. That is why the expression a || b && c is evaluated as a || (b && c). When in doubt, add parentheses explicitly.
AND, OR, XOR, NOT and the Truth Table
Let's start with the OR (|), AND (&), XOR (^), and NOT (!) operators. OR, AND, and XOR are binary operators: they require two operands. NOT is a unary operator: it operates on a single operand. The results of these operations are summarized in the truth table:
| A | B | A & B | A | B | A ^ B | !A |
|---|---|---|---|---|---|
| false | false | false | false | false | true |
| false | true | false | true | true | true |
| true | false | false | true | true | false |
| true | true | true | true | false | false |
The short-circuit operators && and || produce exactly the same results as & and | — the only difference is how the operands are evaluated (see the next section).
OR (|) — the result is true if at least one operand is true. Example: for a child to be picked up from daycare, either the mother or the father (or both) must come — in each of these cases the result is positive. If neither comes, the child is not picked up — the result is negative.
AND (&) — the result is true only if both A and B are true. Example: for a wedding to take place, both the bride (A) and the groom (B) must show up; otherwise there is no wedding.
XOR (^) — the result is true only if the operands differ: exactly one of them is true. Example: two friends share one bicycle — a ride happens only if exactly one of them rides. They cannot ride together, and if neither rides, there is no ride either.
NOT (!) — inverts the value: true becomes false, and vice versa.
Let's look at an example of using the logical operators:
public class BooleanLogic1 {
public static void main(String[] args) {
boolean a = true;
boolean b = false;
boolean c = a | b;
boolean d = a & b;
boolean e = a ^ b;
boolean f = (!a & b) | (a & !b);
boolean g = !a;
System.out.println("a = " + a); // true
System.out.println("b = " + b); // false
System.out.println("a | b = " + c); // true
System.out.println("a & b = " + d); // false
System.out.println("a ^ b = " + e); // true
System.out.println("(!a & b) | (a & !b) = " + f); // true
System.out.println("!a = " + g); // false
}
} Note: the same symbols &, |, ^ applied to integer operands perform bitwise operations on their binary representation — that is a separate topic.
Short-Circuit Operators && and ||
Most of the time, Java code uses the so-called short-circuit logical operators: && — short-circuit AND, and || — short-circuit OR. The Java Language Specification calls them conditional operators (conditional-and, conditional-or).
The right operand of a short-circuit operation is evaluated only when the result depends on it: for && — when the left operand is true, for || — when the left operand is false. Otherwise the result is already known, and the right operand is skipped.
In the following example, the right operand num / d > 10 is never evaluated: the condition d != 0 is false, so the whole expression is false, and the division by zero never happens:
public class BooleanLogic2 {
public static void main(String[] args) {
int d = 0;
int num = 10;
if (d != 0 && num / d > 10) {
System.out.println("num = " + num);
}
}
} If you rewrite this expression with the regular operator — d != 0 & num / d > 10 — the right operand is evaluated unconditionally, and the program terminates with a runtime exception: ArithmeticException: / by zero (integer division by zero).
The same technique protects against NullPointerException — one of the most common practical patterns in Java:
String s = null;
if (s != null && !s.isEmpty()) { // s.isEmpty() is not called, no NPE
System.out.println(s);
} Important
Do not confuse & with && (or | with ||): they produce the same result, but the single-character operators always evaluate both operands, while the short-circuit ones may skip the right operand. Use && and || in conditions by default; reach for & and | only when the right operand must run in every case — for example, when it contains a method call with a required side effect.
Comparing boolean Values: == and !=
To compare two boolean values, Java provides the comparison operators == (equality) and != (inequality):
public class BooleanLogic4 {
public static void main(String[] args) {
boolean b1 = true;
boolean b2 = false;
System.out.println(b1 == b2); // false
System.out.println(b1 != b2); // true
}
} Note that for boolean operands, != gives the same result as ^: true when the operands differ. You cannot compare a boolean with a number — the expression true == 1 does not compile in Java.
Compound Assignment Operators: &=, |=, ^=
The AND, OR, and XOR operators have compound assignment forms. The statement a &= b is equivalent to a = a & b:
public class BooleanLogic5 {
public static void main(String[] args) {
boolean b1 = true;
boolean b2 = true;
b1 &= b2; // same as b1 = b1 & b2;
System.out.println(b1); // true
b1 |= b2; // same as b1 = b1 | b2;
System.out.println(b1); // true
b1 ^= b2; // same as b1 = b1 ^ b2;
System.out.println(b1); // false
}
} The operators &&= and ||= do not exist in Java — compound assignments are available only for the single-character &, |, ^, and their right operand is always evaluated.
Common Pitfalls
If you need to check whether a variable falls within a range, the mathematical notation a < x < b does not compile in Java. Such a condition must be split into two comparisons joined by the && operator: a < x && x < b:
public class BooleanLogic3 {
public static void main(String[] args) {
int a = 1;
int b = 2;
int x = 3;
System.out.print(a < x && x < b); // false: 3 is not between 1 and 2
// System.out.print(a < x < b); // Compilation error!
}
} Important
The notation a < x < b does not work because the expression is evaluated left to right: first a < x produces a boolean, and then the compiler tries to compare that boolean with the number b — no such operation exists in Java. Always write a < x && x < b.
Two more situations that regularly come up in job interviews:
// 1. Precedence: && binds tighter than ||
boolean r = true || false && false; // true: evaluated as true || (false && false)
// 2. A single & does not protect you from an exception
String s = null;
// if (s != null & !s.isEmpty()) {} // NullPointerException: the right operand is always evaluated Frequently Asked Questions
What is the difference between && and & in Java?
For boolean operands both operators produce the same result, but && uses short-circuit evaluation: if the left operand is false, the right operand is not evaluated at all. The single & always evaluates both operands, and for integers it performs a bitwise AND. Use && in conditions by default.
What is short-circuit evaluation?
It is an evaluation strategy in which the right operand of && or || is evaluated only when the result depends on it. For example, in the expression s != null && s.isEmpty(), the isEmpty() method is not called when s == null, which protects against NullPointerException. The Java Language Specification calls these operators conditional.
Why doesn't the expression a < x < b compile in Java?
The expression is evaluated left to right: a < x produces a value of type boolean, and then the compiler tries to compare that boolean with the number b, which is not allowed in Java. A range check is written as two comparisons joined by AND: a < x && x < b.
Does Java have the &&= and ||= operators?
No. Compound assignment operators exist only for the single-character logical operators: &=, |=, and ^=. They do not short-circuit — the right-hand side is always evaluated. If you need short-circuit semantics, write the full form: a = a && b.
Comments