1. Introduction
Let’s start with an everyday analogy. Imagine a recipe:
Mix flour, eggs, and sugar, whisk, add butter, whisk again.
Looks odd? Now imagine that there is a comma or parentheses between the words “whisk” and “add”. The order of actions becomes clearer right away.
In programming, a similar situation arises when you write a complex expression:
boolean result = a > 0 && b < 10 || c == 3;
What’s the order? What is evaluated first: a > 0 && b < 10, then || c == 3? Or the other way around?
Without a clear evaluation order, the computer can “mix up the ingredients,” and your result will be unexpected.
2. Operator precedence in Java
Java (like most programming languages) uses a defined operator precedence table.
Operators with higher precedence are evaluated before operators with lower precedence.
Look at the most important part of this table (for conditional expressions):
| Operator | Description | Precedence |
|---|---|---|
|
Parentheses | highest |
|
Logical “NOT” | high |
|
Equal / not equal | medium |
|
Comparisons | medium |
|
Logical “AND” | lower |
|
Logical “OR” | even lower |
(There are also arithmetic operators—they have higher precedence than logical ones.)
The main rule
“AND” operators (&&) have higher precedence than “OR” (||),
that is, AND is evaluated before OR. It’s no accident that AND is logical multiplication, and OR is addition.
Flowchart for evaluating condition precedence
graph LR
A["a > 0"] --&&--> B["b < 10"]
B --||--> C["c == 3"]
(In practice: a > 0 && b < 10 || c == 3 — first a > 0 && b < 10 is evaluated, then the result is combined with c == 3 via ||.)
3. Operator direction: left to right and right to left
Besides precedence, there is also the notion of associativity.
It determines the direction in which operators are evaluated when they are “next to each other” and have the same precedence.
Example:
boolean a = true, b = false, c = true;
boolean result = a && b && c;
Question: how will it be evaluated?
Answer: the associativity of && is left to right.
So first a && b, then that result with c.
For conditionals:
| Operator | Associativity |
|---|---|
|
left to right |
|
right to left |
4. Parentheses—your best friend in complex conditionals
Here’s where the magic (and the rescue) begins. When you write an expression, parentheses change precedence and make your code clearer and safer.
Example 1 (without parentheses):
// We want: "If the user is an adult and a citizen, or if they have a special permit"
boolean isAdult = age >= 18;
boolean isCitizen = country.equals("Belarus");
boolean hasPermit = hasSpecialPass == true;
if (isAdult && isCitizen || hasPermit)
{
System.out.println("Access granted!");
}
How Java evaluates it:
First it evaluates isAdult && isCitizen, then it compares the result via || with hasPermit.
- Suppose, isAdult = true, isCitizen = false, hasPermit = true
- isAdult && isCitizen → true && false → false
- false || true → true
That is, if a person has a special permit, they will still be allowed in.
And if they don’t have a special permit but are an adult citizen—they will be allowed in as well.
Example 2 (with parentheses):
if (isAdult && (isCitizen || hasPermit))
{
System.out.println("Access granted!");
}
Now the program first checks isCitizen || hasPermit, and then combines that result with isAdult.
That is, you need to be an adult and (either a citizen or have a special permit).
A small difference in parentheses—a huge difference in logic!
GO TO FULL VERSION