As a tech lead, how would you set a team policy around operator precedence to prevent subtle bugs, and where do you draw the line between relying on the table and using explicit parentheses?
answer
- Policy targets the reader, not the parser
- Let universal precedence stand; parenthesize family mixes
- Bitwise+comparison and && + || are the real traps
- Enforce via linters/CI, not memory
- Ban side effects in compound expressions
basics
~20 sLet obvious arithmetic precedence stand (a * b + c), but require parentheses whenever you mix different operator families — especially bitwise with comparison, or assignment/ternary in chains. Back it with linter rules so it's automatic, not memory.
solid answer
~50 sThe policy should optimize for the reader, not the parser. I let universally-known precedence stand un-parenthesized — `a * b + c`, `x > 0 && y > 0` — because over-parenthesizing those just adds noise. But I require explicit parentheses whenever operator *families* mix in non-obvious ways: bitwise (`& | ^`) next to comparison or shifts, ternary nesting, assignment chaining, and anything combining `&&` with `||`. These are exactly the spots where the intuitive reading diverges from the actual grouping. Crucially, I make it automatic: enable IntelliJ/Checkstyle/SpotBugs inspections for unclear precedence and unparenthesized bitwise-in-comparison, so review doesn't depend on someone remembering the table. I also discourage side effects inside compound expressions, which removes whole classes of order-dependent bugs. The principle: precedence is a fallback the language guarantees, but in shared code, parentheses that encode intent are cheaper than the bug or the code-review argument they prevent.
go deeper
Follows the convention (add parentheses when mixing operator types) without yet owning the policy.
Can articulate which operator mixes need parentheses and applies the team's linter rules.
Justifies the policy by the reader-vs-parser distinction and identifies the real traps (bitwise/comparison, && + ||, nested ternary).
Treats precedence as a systemic defect source: sets conventions, wires enforcement into CI tooling, bans side effects in compound expressions, and trains the team rather than relying on recall.
## Framing: the table is correct but the reader is the risk Operator precedence is fully specified and deterministic — code will do exactly what the table says. The risk is not the compiler; it is the **human** who misreads the grouping and introduces or fails to catch a bug. A precedence policy is therefore a *readability and defect-prevention* policy, not a correctness one. ## Where to let precedence stand Over-parenthesizing harms readability too (`((a) * (b)) + (c)` is noise). Let well-known, taught-everywhere precedence stand bare: - Arithmetic: `a * b + c`, `a + b - c`. - Single-family boolean: `x > 0 && y < 10` (relational clearly binds inside `&&`). - A single ternary: `cond ? a : b`. These are part of every developer's mental model; parentheses add clutter without adding clarity. ## Where to mandate parentheses Require explicit grouping where intuition and the table diverge: - **Bitwise mixed with comparison/shift**: `(flags & MASK) != 0`, `(x >> 2) & 0xFF`. (`==` outranks `&`; `+` outranks `<<`.) - **Mixing `&&` with `||`**: `(a && b) || c` — many readers misremember that `&&` binds tighter than `||`. - **Nested ternaries**: parenthesize or, better, refactor to `if`/`switch`. - **Assignment used as a value** or chained: avoid `if ((x = next()) != null)` ambiguity by making intent explicit; ban deep chains. - **Bitwise across `& ^ |`**: their relative order surprises people; parenthesize. ## Make it mechanical, not cultural A policy enforced by memory and code review will erode. Encode it in tooling: - IntelliJ inspection 'Overly complex/unclear precedence' and 'Unnecessary/Required parentheses'. - Checkstyle, SpotBugs/Error Prone rules for unparenthesized bitwise-in-comparison and confusing operator combos. - Make the linter a CI gate so violations cannot merge. ## Remove the second variable: side effects Most precedence-related production bugs get worse when operands have **side effects**, because then evaluation order (left-to-right in Java) compounds the grouping confusion. So pair the parentheses policy with a rule to **keep side effects out of compound expressions** — extract to statements with names. This collapses two hard-to-reason-about rules (grouping + timing) into simple sequential code. ## The line, stated as a principle Rely on precedence only for groupings that are universal knowledge; parenthesize the moment a reasonable engineer might pause. Parentheses and named intermediate variables are nearly free; the bugs and review debates they prevent are not. Push the enforcement into automated tooling so the standard is consistent and not a matter of individual recall. ## How a principal demonstrates this Not by reciting the table, but by treating precedence as a *systemic* defect source: setting conventions, wiring linters into CI, training the team on the handful of genuine traps (bitwise/comparison, `&&`/`||`, ternary nesting), and pushing for side-effect-free expressions so the rules rarely even apply.
- Why not just require parentheses everywhere to be safe?Because excessive parentheses add visual noise that hurts readability as much as missing ones, and they train readers to ignore them. The goal is to clarify the non-obvious groupings while leaving universally-understood precedence (a * b + c) clean.
- How does removing side effects from expressions reduce precedence bugs?Precedence sets grouping and Java's left-to-right rule sets timing; both only bite when operands have side effects. Extracting side-effecting calls into named statements removes the timing variable entirely, so only simple grouping remains.
saying these in an interview costs you the question
- Mandating parentheses around everything (noise, harms readability)
- Relying purely on code review or memory instead of tooling
- Ignoring that side effects + evaluation order amplify precedence confusion
- Treating precedence as a correctness problem rather than a readability/defect one