I have two similar questions about operator precedences in Java.
First one:
int X = 10;
System.out.println(X++ * ++X * X++); //it prints 1440
According to Oracle tutorial:
postfix (expr++, expr–) operators have higher precedence than prefix (++expr, –expr)
So, I suppose that evaluation order:
1) first postfix operator: X++
1.a) X++ "replaced" by 10
1.b) X incremented by one: 10+1=11
At this step it should look like: System.out.println(10 * ++X * X++), X = 11;
2) second POSTfix operator: X++
2.a) X++ "replaced" by 11
2.b) X incremented by one: 11+1=12
At this step it should look like: System.out.println(10 * ++X * 11), X = 12;
3) prefix operator: ++X
3.a) X incremented by one: 12+1=13
3.b) ++X "replaced" by 13
At this step it should look like: System.out.println(10 * 13 * 11), X = 13;
4) evaluating 10*13 = 130, 130*11 = 1430.
But Java seems to ignore PRE/POST ordering and puts them on one level. So the real order:
X++ -> ++X -> X++
what causes the answer to be (10 * 12 * 12) = 1440.
Second one:
int a=1, b=2;
a = b + a++;
Part of accepted answer:
"By the time of assignment, ++
has already incremented the value of a
to 2
(because of precedence), so =
overwrites that incremented value."
OK, let's look step-by-step:
1) replacing "b" with 2
2) replacing "a++" with 1
3) incrementing "a" by 1 -> at this point a==2
4) evaluating 2+1 = 3
5) overwriting incremented value of "a" with 3
Seems everything is fine.
But let's make a little change in that code (replace "=" with "+=")
a += b + a++;
steps 1-4 should be same as above.
so, after step 4 we have something like that:
a += 3;
where a==2
And then I think: OK, a = 2+3
, so a
should be 5
. BUT the answer is only 4
I'm really confused. I already spent couple of hours but still can't understand where I am wrong.
P.S. I know, that I shouldn't use this "style" in real applications. I just want to understand what is wrong in my thoughts.
Best Answer
The confusion stems from the fact that the operands are evaluated from left to right. This is done first, before any attention is paid to operator precedence/order of operations.
This behavior is specified in JLS 15.7.2. Evaluate Operands before Operation
So
X++ * ++X * X++
is first evaluated as10 * 12 * 12
which yields, as you saw, 1440.To convince yourself of this, consider the following:
If
X++
were done first, then++X
second, then multiplication, both should print the same number.But they do not:
So how does this make sense? Well if we realize that operands are evaluated from left to right, then it makes perfect sense.
The first line looks like
and the second
So why are prefix and postfix increment/decrement operators in the table?
It is true that increment and decrement must be performed before multiplication. But what that is saying is that:
Just as
It remains that the order of the evaluation of the operands occurs left-to-right.
If you're still not conviced:
Consider the following program:
If the arguments were evaluated at the time they were needed, either
b
orc
would come first, the other next, and lastlya
. However, the program outputs:Because, regardless of the order that they're needed and used in the equation, they're still evaluated left to right.
Helpful reading: