Classes/Objects  «Prev  Next»


Lesson 8 Determining order of evaluation
ObjectiveDescribe how operator precedence and associativity is used.

Java Operator Precedence Associativity

Operator Precedence and Associativity in Java SE 21
In Java, 1) operator precedence and 2) associativity determine the order in which operators are evaluated in expressions. Understanding these concepts is essential for writing correct and efficient code.
1) Operator Precedence: Operator precedence defines the order in which different operators are evaluated in an expression. Operators with higher precedence are evaluated before operators with lower precedence.
Operator Precedence Table Below is a comprehensive list of Java operators ordered from highest to lowest precedence:
  1. Postfix: expr++, expr--
  2. Unary: ++expr, --expr, +expr, -expr, ~, !
  3. Creation or Casting: new, (type)
  4. Multiplicative: *, /, %
  5. Additive: +, -
  6. Shift: <<, >>, >>>
  7. Relational: <, >, <=, >=, instanceof, pattern instanceof (since Java 16)
  8. Equality: ==, !=
  9. Bitwise AND: &
  10. Bitwise XOR: ^
  11. Bitwise OR: |
  12. Logical AND: &&
  13. Logical OR: ||
  14. Ternary Conditional: ?:
  15. Assignment: =, +=, -=, *=, /=, %=, &=, |=, ^=, <<=, >>=, >>>=

Examples

Multiplicative vs. Additive Operators

int result = 2 + 3 * 4;

Evaluation:
  1. Multiplication (*) has higher precedence than addition (+).
  2. Calculate 3 * 4 → 12.
  3. Then add 2 + 12 → 14.

Result: result is 14.

Unary vs. Postfix Operators
int a = 5;
int b = a++;
int c = ++a;

Evaluation:
  1. b = a++; assigns 5 to b, then increments a to 6.
  2. c = ++a; increments a to 7, then assigns 7 to c.

2) Associativity
Associativity determines the order in which operators of the same precedence level are evaluated. It can be left-to-right (left-associative) or right-to-left (right-associative).
Left-Associative Operators
Most binary operators are left-associative.
Example:
int result = 100 / 10 / 2;

Evaluation:
  1. (100 / 10) → 10.
  2. (10 / 2) → 5.

Result: result is 5.
Right-Associative Operators
Assignment operators and the ternary conditional operator are right-associative.
Example:
int x, y, z;
x = y = z = 10;

Evaluation:
  1. z = 10;
  2. y = z;
  3. x = y;

Result: All variables x, y, and z have the value 10.
Non-Associative Operators Some operators are non-associative and cannot be chained without parentheses.
Example:
boolean result = true ? false : true ? false : true;

Evaluation:
  • The ternary operator ?: is right-associative.
  • Evaluates as true ? false : (true ? false : true);

Special Considerations in Java SE 21 Java SE 21 continues to use the same operator precedence and associativity rules as previous versions. However, it introduces enhancements like pattern matching for switch expressions and record patterns, which can affect how expressions are evaluated.
Pattern Matching for switch:
switch (obj) {
    case String s -> System.out.println("It's a string: " + s);
    case Integer i -> System.out.println("It's an integer: " + i);
    default -> System.out.println("Unknown type");
}

Note: The instanceof operator now supports pattern matching, but this does not change its precedence or associativity.
Tips for Using Operator Precedence and Associativity
  1. Use Parentheses for Clarity: When in doubt, use parentheses to make the order of evaluation explicit.
    int result = 2 + (3 * 4); // Clear and unambiguous
    
  2. Be Mindful of Side Effects: Operators like ++ and -- can have side effects that affect the outcome.
    int i = 0;
    int array[] = {0, 1, 2, 3};
    array[i++] = i;
    // Be cautious with such expressions
    
  3. Understand Short-Circuit Evaluation: Logical operators && and || short-circuit, meaning they don't evaluate the right-hand side if not necessary.
    if (obj != null && obj.isValid()) {
      // Safe to use obj
    }
    
  4. Avoid Complex Expressions: Break down complex expressions into multiple statements for better readability and maintainability.


Common Pitfalls
Mixing Bitwise and Logical Operators:
Remember that & and | are bitwise operators, while && and || are logical operators.
// Bitwise AND
int flags = flag1 & flag2;

// Logical AND
if (condition1 && condition2) { ... }

Assignment in Conditional Statements:
if (x = y) { ... } // Error: assignment instead of comparison

// Correct way
if (x == y) { ... }

The assignment operator = has lower precedence than the equality operator ==, but accidental use can lead to logical errors.
Summary
  • Operator Precedence: Determines the order in which different operators are evaluated.
  • Associativity: Determines the order in which operators of the same precedence level are evaluated.
    • Left-associative: Evaluated from left to right.
    • Right-associative: Evaluated from right to left.
    • Non-associative: Cannot be chained without explicit grouping.
  • Java SE 21: No changes to operator precedence or associativity, but new language features like pattern matching may affect code structure.

By understanding and applying these rules, you can write clearer and more predictable Java code. Always refer to the official Java documentation for the most accurate and detailed information.


Order of Evaluation for Operators

Describe how operator precedence and associativity is used to determine the order in which expressions are evaluated.
The order of evaluation of Java expressions is dependent on the precedence and associativity of the operators used in the expression, and the use of parentheses. In general, the operands of expressions are evaluated in a left-to-right order before any operations are performed. The exceptions to this are expressions involving the &&, ||, and ternary operators.
Once an expression's operands are evaluated, the operators are applied according to operator precedence and associativity. The assignment operator is the only right-associative binary operator. Parentheses can be used to change the ordering imposed by precedence and associativity.
The following table shows the precedence of Java's operators. Higher-level operators take precedence over lower-level operators.
Operators at the same level are evaluated based on the order they appear and their associativity.
  1. Order of evaluation: The order in which expressions are evaluated.
  2. Precedence: The order in which operations are performed.

Modern Java
Operator precedence table
Operator precedence table

Modern Java
Java already has a rule in place for just such a situation. Table 4.8 lists the precedence of operators: the operator on top has the highest precedence, and operators within the same group have the same precedence and are evaluated from left to right.
Table 4.8  Precedence of operators
Table 4.8 Precedence of operators

Let us execute an expression that uses multiple operators (with different precedence) in an expression:

int int1 = 10, int2 = 20, int3 = 30;
System.out.println(int1 % int2 * int3 + int1 / int2);

Prints 300
Because this expression defines multiple operators with different precedence, it is evaluated as follows:
(((int1 % int2) * int3)) + (int1 / int2)
(((10 % 20) * 30)) + (10 / 20)
( (10 * 30)) + (0)
( 300 )
Java Operator Precedence
The Precedence program provides an example of how complex expressions are evaluated.

SEMrush Software