2.6 Evaluation Order of Operands
To understand the result returned by an operator, it is important to understand the evaluation order of its operands. In general, the operands of operators are evaluated from left to right. The evaluation order also respects any parentheses, and the precedence and associativity rules of operators.
Examples illustrating how the operand evaluation order influences the result returned by an operator can be found in §2.7, p. 54, and §2.10, p. 69.
Left-Hand Operand Evaluation First
The left-hand operand of a binary operator is fully evaluated before the right-hand operand is evaluated.
The evaluation of the left-hand operand can have side effects that can influence the value of the right-hand operand. For example, in the code
int b = 10;
System.out.println((b=3) + b);
the value printed will be 6 and not 13. The evaluation proceeds as follows:
Click here to view code image
(b=3) + b
3 + b b is assigned the value 3
3 + 3
6
If evaluation of the left-hand operand of a binary operator throws an exception (§7.1, p. 365), we cannot rely on the presumption that the right-hand operand has been evaluated.
Operand Evaluation before Operation Execution
Java guarantees that all operands of an operator are fully evaluated before the actual operation is performed. This rule does not apply to the short-circuit conditional operators &&, ||, and ?:.
This rule also applies to operators that throw an exception (the integer division operator / and the integer remainder operator %). The operation is performed only if the operands evaluate normally. Any side effects of the right-hand operand will have been effectuated before the operator throws an exception.
Example 2.1 illustrates the evaluation order of the operands and precedence rules for arithmetic expressions. We use the eval() method at (3) in Example 2.1 to demonstrate integer expression evaluation. The first argument to this method is the operand value that is returned by the method, and the second argument is a string to identify the evaluation order.
The argument to the println() method in the statement at (1) is an integer expression to evaluate 2 + 3 * 4. The evaluation of each operand in the expression at (1) results in a call of the eval() method declared at (3).
out.println(eval(j++, ” + “) + eval(j++, ” * “) * eval(j, “\n”)); // (1)
The output from Example 2.1 shows that the operands were evaluated first, from left to right, before operator execution, and that the expression was evaluated as (2 + (3 * 4)), respecting the precedence rules for arithmetic expression evaluation. Note how the value of variable j changes successively from left to right as the first two operands are evaluated.
Example 2.1 Evaluation Order of Operands and Arguments
import static java.lang.System.out;
public class EvalOrder{
public static void main(String[] args){
int j = 2;
out.println(“Evaluation order of operands:”);
out.println(eval(j++, ” + “) + eval(j++, ” * “) * eval(j, “\n”)); // (1)
int i = 1;
out.println(“Evaluation order of arguments:”);
add3(eval(i++, “, “), eval(i++, “, “), eval(i, “\n”)); // (2) Three arguments.
}
public static int eval(int operand, String str) { // (3)
out.print(operand + str); // Print int operand and String str.
return operand; // Return int operand.
}
public static void add3(int operand1, int operand2, int operand3) { // (4)
out.print(operand1 + operand2 + operand3);
}
}
Output from the program:
Evaluation order of operands:
2 + 3 * 4
14
Evaluation order of arguments:
1, 2, 3
6