JB Header

Java Operator Precedence and Associativity Explained

Introduction What is the value of 2 + 3 * 4? In Java, as in mathematics, it is 14, not 20 - because multiplication is done before addition. The rules that decide which operator is applied first are called operator precedence, and the rules for operators of equal precedence are called associativity. This tutorial explains Java operator precedence and associativity. We will start with what each term means. We will then go through Java's precedence table, from the highest precedence to the lowest. Next we will run examples of the cases which most often cause bugs. Lastly, we will see how the order of evaluation differs from precedence, and why parentheses are your best friend.

(Note - This tutorial brings together the operators from Arithmetic, Relational and Logical OperatorsClick to read tutorial: Java Arithmetic, Relational and Logical Operators, Bitwise and Shift OperatorsClick to read tutorial: Java Bitwise and Shift Operators with Examples and Assignment and Ternary OperatorsClick to read tutorial: Java Assignment, Increment/Decrement and Ternary Operators.) Precedence and associativity
  • Precedence decides which of two different operators binds more tightly. * has higher precedence than +, so 2 + 3 * 4 is grouped as 2 + (3 * 4).
  • Associativity decides how operators of the same precedence are grouped. Most binary operators are left-associative, so 20 - 5 - 3 is (20 - 5) - 3 = 12. Assignment, the ternary operator and the unary operators are right-associative, so a = b = 0 is a = (b = 0).
  • Parentheses override both. Whatever is inside ( ) is grouped first.
Java operator precedence table Operators higher in the table are applied before operators lower down. Operators on the same row have equal precedence.
#OperatorsDescriptionAssociativity
1x++ x--Postfix increment, decrement-
2++x --x +x -x ~ !Prefix increment/decrement, unary plus/minus, bitwise NOT, logical NOTRight to left
3(type) newCast, object creationRight to left
4* / %MultiplicativeLeft to right
5+ -Additive (and string joining)Left to right
6<< >> >>>ShiftLeft to right
7< > <= >= instanceofRelational, type testLeft to right
8== !=EqualityLeft to right
9&Bitwise ANDLeft to right
10^Bitwise XORLeft to right
11|Bitwise ORLeft to right
12&&Logical ANDLeft to right
13||Logical ORLeft to right
14? :Ternary (conditional)Right to left
15= += -= *= /= %= &= ^= |= <<= >>= >>>=AssignmentRight to left
16->Lambda arrowRight to left

A handy way to remember the main groups is: unary, then arithmetic (multiply before add), then shift, then comparison, then bitwise, then logical (AND before OR), then ternary, then assignment.
Precedence in action
Examples of precedence and associativity
//PrecedenceDemo.java
public class PrecedenceDemo {
  public static void main(String[] args) {
    System.out.println("2 + 3 * 4       = " + (2 + 3 * 4));
    System.out.println("(2 + 3) * 4     = " + ((2 + 3) * 4));
    System.out.println("20 - 5 - 3      = " + (20 - 5 - 3));
    System.out.println("100 / 10 / 2    = " + (100 / 10 / 2));
    System.out.println("10 - 4 % 3      = " + (10 - 4 % 3));
    System.out.println("-2 * -3         = " + (-2 * -3));

    int a = 5, b = 10;
    System.out.println("a + b > 12      = " + (a + b > 12));
    System.out.println("1 << 2 + 1      = " + (1 << 2 + 1));
    System.out.println("(double) 7 / 2  = " + ((double) 7 / 2));

    boolean t = true, f = false;
    System.out.println("t || f && f     = " + (t || f && f));
    System.out.println("(t || f) && f   = " + ((t || f) && f));
    System.out.println("!t == f         = " + (!t == f));
  }
}
 OUTPUT of the above code
2 + 3 * 4       = 14
(2 + 3) * 4     = 20
20 - 5 - 3      = 12
100 / 10 / 2    = 5
10 - 4 % 3      = 9
-2 * -3         = 6
a + b > 12      = true
1 << 2 + 1      = 8
(double) 7 / 2  = 3.5
t || f && f     = true
(t || f) && f   = false
!t == f         = true
Explanation of the code
  • 20 - 5 - 3 and 100 / 10 / 2 are evaluated left to right, giving 12 and 5. Grouping from the right would give 18 and 20.
  • % has the same precedence as *, so 10 - 4 % 3 is 10 - 1 = 9.
  • a + b > 12 works without parentheses because arithmetic comes before comparison.
  • 1 << 2 + 1 is 1 << 3 = 8, because + is applied before << - a surprise for many programmers.
  • A cast applies only to the value right after it, so (double) 7 / 2 casts 7 and then divides, giving 3.5.
  • && binds more tightly than ||, so t || f && f is t || (f && f) = true. With parentheses forcing the OR first, the result is false.
Common precedence traps Two mistakes come up again and again. The first mixes string joining with arithmetic, and the second mixes bitwise operators with comparisons.
Two common precedence traps
//PrecedenceTraps.java
public class PrecedenceTraps {
  public static void main(String[] args) {
    int x = 2, y = 3;
    System.out.println("Sum: " + x + y);
    System.out.println("Sum: " + (x + y));
    System.out.println(x + y + " is the sum");

    int flags = 6;
    int MASK = 4;
    System.out.println("flag set: " + ((flags & MASK) != 0));
  }
}
 OUTPUT of the above code
Sum: 23
Sum: 5
5 is the sum
flag set: true
Explanation of the code
  • "Sum: " + x + y is evaluated left to right. "Sum: " + x gives the string "Sum: 2", and adding y joins "3" to it - printing Sum: 23. Parentheses make the addition happen first.
  • x + y + " is the sum" works without parentheses, because the two numbers are added before any string is involved.
  • == and != have higher precedence than &, so flags & MASK != 0 would mean flags & (MASK != 0) - an int AND a boolean, which does not compile. Always put parentheses around a bitwise test: (flags & MASK) != 0.
Precedence vs order of evaluation Precedence decides how an expression is grouped, not the order in which its parts are evaluated. Java always evaluates the operands of an operator from left to right - the left operand is fully evaluated before the right one, even when the right side has higher precedence.
Operands are evaluated left to right
//EvaluationOrder.java
public class EvaluationOrder {
  static int value(String name, int v) {
    System.out.println("  evaluating " + name);
    return v;
  }

  public static void main(String[] args) {
    int result = value("a", 1) + value("b", 2) * value("c", 3);
    System.out.println("result = " + result);

    int i = 2;
    int j = i + i++ * 10;   // the left i is read (2) before i++ runs
    System.out.println("j = " + j + ", i = " + i);
  }
}
 OUTPUT of the above code
  evaluating a
  evaluating b
  evaluating c
result = 7
j = 22, i = 3
Explanation of the code
  • Although b * c is calculated before the addition, the operands were evaluated in the order a, b, c.
  • In i + i++ * 10, the left i is read first (2), then i++ gives 2 and sets i to 3, so j is 2 + 2 × 10 = 22. Code like this is legal but confusing - avoid it.
Best practice: you do not need to memorize the whole table. Learn the main groups, and add parentheses whenever the grouping is not obvious. They cost nothing at runtime, and make the code clear to every reader. Summary In this tutorial we first defined precedence, which decides how different operators are grouped, and associativity, which decides how operators of equal precedence are grouped. We then went through Java's operator precedence table, from postfix operators down to assignment and lambdas. Next we ran examples of precedence in action, and two common traps - string joining with +, and bitwise tests without parentheses. Lastly, we saw that operands are always evaluated left to right, independently of precedence, and that parentheses are the best way to make the grouping clear. In the next tutorial, we will learn to format output with println, printf and String.formatClick to read tutorial: Java Console Output: println, printf and String.format.