Edit: I do not understand the answers others have given completely, but this is my best guess at what is happening. If someone wants to correct this guess, please do so.
My best guess:
a + b * c
, where a, b, and c are variables, is made into an expression tree, where the operator with lowest precedence is at the top of the tree:
+
/ \
a *
/ \
b c
Now, this tree is evaluated like so: the + operator gets evaluated. To do so, it (recursively) evaluates the left subtree, and its right subtree, then adds these values.
In full, this is what happens:
- addition operator gets evaluated.
it says "evaluate my left subtree, then my right subtree,
then add them together. i return that value"
- left subtree: is a. evaluate variable a into a value.
(that is, get the value of variable a.)
- right subtree: i'm a multiplication operator. to evaluate me,
evaluate my left subtree, then my right subtree, the nmultiply
them togeter. i return that value.
- left subtree: is variable b. evalute that.
- right subtree: is variable c. evaluate that.
This is why it a
finishes its evaluation first, then b
, then c
, then b * c
, then a + (b * c)
In expressions with ++i stuff, the same thing happens. For example, with ++i + i++
, the expression tree would look like this:
+
/ \
preinc postinc
| |
i i
where (for example) preinc means the preincrement operator (and preincrement operator takes exactly one operand: a variable). the difference here is that when the subtree that has preinc as its root needs to get evaluated, to "evaluate the preinc operator tree" doesn't mean "replace the variable in the operand with the value of the variable" (the way it would for, say, 2 + i ), but instead it means "increment the value in variable i, and then the value of preinc(i) is the new value in the variable i".
in a similar way, the assignment operator = works a little differently than, say, 2 + i.
int j;
j = 3;
the expression tree here is
=
/ \
j 3
and when a tree with assignment operator as its root needs to get evaluated, this means "the left hand operator must be a variable -- not a value! and then evaluate the right subtree (we expect it to evaluate it to a value), and then put the value in the right subtree in the variable in the left subtree. Now, the value returned by =(j, 3) is the value in the right subtree".
with this guess, I'm able to correctly come up with the answers given for examples in the Java Language Specification on Evaluation Order (link is: https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.7).
that is, if i draw the expression tree, the following two examples are solvable by me:
example:
int i = 2;
int j = (i = 3) * i;
System.out.println(j);
example:
int b = 9;
b = b + (b = 3);
System.out.println(b);