Operator Precedence & Associativity
When an expression mixes several operators, precedence decides which one binds tighter, and associativity decides how operators of equal precedence group together.
An expression like a + b * c - d / e involves multiple operators competing for the same operands. Java resolves this ambiguity with two rules: precedence, which determines which operator 'binds' more tightly (evaluates first) than another, and associativity, which determines how a sequence of operators with the same precedence groups — left to right or right to left. Knowing the rules matters less than knowing when to stop relying on them and use parentheses instead.
What Precedence Means
Precedence ranks operators by priority. A higher-precedence operator groups with its operands before a lower-precedence one does, exactly as 'multiplication before addition' works in ordinary arithmetic.
int result = 2 + 3 * 4; // * has higher precedence than +
System.out.println(result); // 14, not 20 — evaluated as 2 + (3 * 4)The Precedence Table (High to Low, Simplified)
Java's full precedence table has many levels; the commonly relevant ones, from highest to lowest priority, are summarized below. Operators higher in the list bind more tightly.
1. postfix expr++ expr--
2. unary ++expr --expr +expr -expr ! ~
3. multiplicative * / %
4. additive + -
5. shift << >> >>>
6. relational < > <= >= instanceof
7. equality == !=
8. bitwise AND &
9. bitwise XOR ^
10. bitwise OR |
11. logical AND &&
12. logical OR ||
13. ternary ?:
14. assignment = += -= *= /= %= &= ^= |= <<= >>= >>>=Associativity
When two operators in the same expression share the same precedence level, associativity decides which one groups first. Almost all Java binary operators are left-associative (grouped left to right); assignment operators and the ternary operator are the notable right-associative exceptions.
int result = 20 - 5 - 3; // left-associative: (20 - 5) - 3 = 12, not 20 - (5 - 3) = 18
System.out.println(result); // 12
int a, b, c;
a = b = c = 5; // right-associative: a = (b = (c = 5))Parentheses Override Everything
Explicit parentheses always take priority over the default precedence and associativity rules — the enclosed sub-expression is evaluated as a unit before it participates in the surrounding expression.
int result = (2 + 3) * 4; // parentheses force + before *
System.out.println(result); // 20, not 14Arithmetic Precedence Examples
System.out.println(10 + 2 * 3); // 16 (multiplicative before additive)
System.out.println((10 + 2) * 3); // 36 (parentheses override)
System.out.println(10 - 4 / 2); // 8 (division before subtraction)
System.out.println(2 + 3 * 4 - 6 / 3); // 2 + 12 - 2 = 12Logical Precedence Examples
&& binds tighter than ||, meaning an expression mixing both is grouped as if the && sub-expressions were parenthesized first — a very common source of subtle bugs when the intended grouping is actually the opposite.
boolean result = true || false && false;
// grouped as: true || (false && false)
System.out.println(result); // true
boolean confusing = false || true && false;
// grouped as: false || (true && false) -> false || false
System.out.println(confusing); // falseRelational, Equality, and instanceof Precedence
Relational operators (including instanceof) bind tighter than equality operators, which bind tighter than the logical operators — this ordering usually matches programmer intuition, but it's worth confirming when combining several comparisons.
int age = 25;
boolean eligible = age >= 18 && age < 65;
// grouped as: (age >= 18) && (age < 65) — matches intent naturallyAssignment Precedence and the ?: Operator
Assignment has the lowest precedence of the common operators, so the entire right-hand side of = is evaluated first, as a whole, before the assignment happens. The ternary operator ?: also sits low in the table and is right-associative, which is what makes chained/nested ternaries like a ? b : c ? d : e group as a ? b : (c ? d : e).
int x = 2 + 3 * 4; // right side fully evaluated (14) before assignment to x
int grade = (score >= 90) ? 4 : (score >= 80) ? 3 : (score >= 70) ? 2 : 1;
// right-associative grouping: (score>=90) ? 4 : ((score>=80) ? 3 : ((score>=70) ? 2 : 1))Common Precedence Pitfalls
A few precedence interactions catch even experienced developers off guard, especially around bitwise vs. equality operators, and unary vs. binary minus.
// Bitwise AND has LOWER precedence than equality — a classic trap
int flags = 0b0110;
// if (flags & 0b0010 == 0b0010) { ... } // WRONG: parsed as flags & (0010 == 0010), a type-mismatch compile error
if ((flags & 0b0010) == 0b0010) { ... } // correct: parentheses force intended groupingBest Practice: Don't Rely on Memorization
Java's precedence table has over a dozen levels, and few developers have it perfectly memorized — nor should they need to. When an expression mixes more than two or three different operator types, adding explicit parentheses (even 'unnecessary' ones that match the default grouping) makes the intended grouping unambiguous to every future reader, at essentially zero runtime cost.
// Technically correct without parens, but harder to read at a glance:
boolean result = a > b && c < d || e == f;
// Same logic, unambiguous at a glance:
boolean resultClear = (a > b && c < d) || (e == f);Complete Example
public class PrecedenceDemo {
public static void main(String[] args) {
int a = 5, b = 10, c = 2;
int r1 = a + b * c; // 25: * before +
int r2 = (a + b) * c; // 30: parens override
int r3 = a > 3 && b < 20 || c == 0; // grouped as (a>3 && b<20) || (c==0) -> true
System.out.println(r1);
System.out.println(r2);
System.out.println(r3);
int x, y;
x = y = 5 + 5; // right-associative assignment: y=(5+5)=10, then x=y=10
System.out.println(x + " " + y);
}
}Quick Reference
Higher precedence binds tighter and evaluates first (as a group)
Most binary operators: left-associative
Assignment and ?: : right-associative
Multiplicative (*, /, %) before additive (+, -)
Relational/instanceof before equality (==, !=)
Equality before bitwise (&, ^, |)
Bitwise before logical (&&, ||)
Logical before ternary (?:) before assignment (lowest)
Parentheses always override default precedence/associativityKey Takeaways
Precedence determines which operator binds first when several appear in one expression; associativity resolves ties between operators of equal precedence.
Most Java operators are left-associative; assignment operators and the ternary operator are right-associative.
&& binds tighter than ||; relational/instanceof bind tighter than equality; equality binds tighter than bitwise operators — mixing them without parentheses can silently produce unintended grouping.
Parentheses always override default precedence and associativity, and are the safest way to express intent.
When an expression mixes more than a couple of operator types, prefer explicit parentheses over relying on memorized precedence rules — clarity outweighs the minor verbosity.
if (flags & MASK == MASK) {... } if ((flags & MASK) == MASK) {... }
Equality (==) has higher precedence than bitwise AND (&), so without parentheses the expression is parsed as flags & (MASK == MASK), which is a type mismatch (comparing int to boolean) and fails to compile.
boolean result = a || b && c; // intending (a || b) && c boolean result = (a || b) && c;
&& binds tighter than ||, so a || b && c actually groups as a || (b && c) — the opposite of the intended grouping. Add explicit parentheses when the intended grouping differs from default precedence.
int result = 10 - 5 - 2; // assuming right-associative gives 10 - (5-2) = 7
// Actually left-associative: (10 - 5) - 2 = 3 — this IS the correct/default behavior; // use parentheses only if you actually want the other grouping: int result = 10 - (5 - 2); // = 7, if that's genuinely intended
Subtraction (like most binary operators) is left-associative, not right-associative — a sequence of same-precedence operators groups left to right by default, which can surprise anyone assuming a different convention.
In the expression 2 + 3 * 4, why does the result equal 14 rather than 20?
Multiplication has higher precedence than addition, so 3 * 4 is evaluated first as a group (yielding 12), and then 2 + 12 gives 14.
What does associativity determine, and when does it come into play?
Associativity determines how a sequence of operators that share the same precedence level group together — left to right or right to left. It comes into play whenever two or more operators of equal precedence appear consecutively in an expression, such as 20 - 5 - 3.
Why does the expression true || false && false evaluate to true, and how does precedence explain it?
&& has higher precedence than ||, so the expression groups as true || (false && false), which simplifies to true || false, which is true.
Why is int flags_check = flags & MASK == MASK; a compile error rather than just an unexpected result?
Equality (==) binds tighter than bitwise AND (&), so the expression is parsed as flags & (MASK == MASK). Since MASK == MASK produces a boolean and & is being applied between an int (flags) and a boolean, this is a type mismatch that fails to compile.
Is assignment (=) left-associative or right-associative in Java, and how does a = b = c = 5; demonstrate this?
Assignment is right-associative. The expression groups as a = (b = (c = 5)): c = 5 is evaluated first (assigning 5 to c and evaluating to 5), then b = 5, then a = 5, all ending up with the value 5.
Why is it good practice to add parentheses to an expression even when they don't change the result under the default precedence rules?
Explicit parentheses make the intended grouping unambiguous to any reader, without requiring them to recall Java's full precedence table from memory — this improves readability and reduces the risk of misinterpretation or future editing mistakes, at no runtime cost.
Given int x = 5; int y = 2; int z = x > 3 && y < 10 || x == 0;, what is z, and what is the grouping that produces it?
z is true. The expression groups as (x > 3 && y < 10) || (x == 0), i.e. (true && true) || false = true || false = true.
Add the minimum parentheses to make this expression compute the average of a, b, and c correctly: int avg = a + b + c / 3;
int avg = (a + b + c) / 3;
Without parentheses, / (higher precedence than +) applies only to c, giving a + b + (c / 3), not the intended (a + b + c) / 3. Wrapping the sum in parentheses forces it to be computed first.
What does this print, and what is the grouping (per precedence and left-to-right associativity)?
It prints 5. % and * share the same precedence level and are left-associative, so a % b * c groups as (a % b) * c = (8 % 3) * 2 = 2 * 2 = 4; then + 1 gives 5.
Write an if condition, using explicit parentheses for clarity, that checks: a person is eligible if they are at least 18 AND (they have a valid ID OR they are accompanied by a guardian).
boolean eligible = (age >= 18) && (hasValidId || hasGuardian);
Explicit parentheses group the OR condition together and make the AND-of-(age check)-and-(OR group) structure unmistakable, even though && already binds tighter than || by default — the parentheses remove any need for the reader to rely on precedence rules to see the intended grouping.
int a = 8, b = 3, c = 2;
int result = a % b * c + 1;
System.out.println(result);