Java: pre, postfix operator takes precedence
I have two similar questions about operator precedence in Java
First:
int X = 10; System.out.println(X++ * ++X * X++); //it prints 1440
According to Oracle tutorial: postfix (expr, expr –) operator takes precedence over prefix (expr, – expr)
Therefore, I think this 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 sorting and put them at one level So the real order:
X++ -> ++X -> X++
What causes the answer (10 * 12 * 12) = 1440
the second:
Example from this question:
int a=1,b=2; a = b + a++;
Partial answer: "by the time of transfer, the value of a has been increased to 2 (because of priority), so = overwrite the increased value
OK, let's look at it 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
Everything seems to be fine But let's make a little change in the code (replace "=" with "=")
a += b + a++;
Steps 1-4 should be the same as above So, after step 4, we have something like this:
a += 3;
Where a = = 2
Then I thought: OK, a = 2, 3, so one should be 5 But the answer is only 4
I'm really confused. I've spent hours, but I still don't understand where I'm wrong
PS: I know I shouldn't use this "style" in practical application I just want to know what's wrong with my idea
Solution
This confusion stems from the fact that operands are evaluated from left to right Operate first before any attention is paid to the operator priority / operation sequence
This behavior is described in JLS 15.7 2. Specified in evaluate operators before operation
So x * x * x is first evaluated as 10 * 12 * 12, as you can see, 1440
To convince yourself, consider the following:
X = 10; System.out.println(X++ * ++X); X = 10; System.out.println(++X * X++);
If x is completed first, then x seconds, and then multiply, all should print the same number
But they did not:
X = 10; System.out.println(X++ * ++X); // 120 X = 10; System.out.println(++X * X++); // 121
So what's the point? So if we realize that operands are evaluated from left to right, then this is completely correct
X = 10; System.out.println(X++ * ++X); // 120 (10 * 12) X = 10; System.out.println(++X * X++); // 121 (11 * 11)
The first line looks like
X++ * ++X 10 (X=11) * (X=12) 12 10 * 12 = 120
And second
++X * X++ (X=11) 11 * 11 (X=12) 11 * 11 = 121
So why are prefix and suffix increment / decrement operators in the table?
Indeed, increment and decrement must be performed before multiplication But it means:
Y = A * B++ // Should be interpreted as Y = A * (B++) // and not Y = (A * B)++
Like
Y = A + B * C // Should be interpreted as Y = A + (B * C) // and not Y = (A + B) * C
Still, the evaluation order of operands is from left to right
If you haven't won yet:
Consider the following procedures:
class Test { public static int a(){ System.out.println("a"); return 2; } public static int b(){ System.out.println("b"); return 3; } public static int c(){ System.out.println("c"); return 4; } public static void main(String[] args) { System.out.println(a() + b() * c()); // Lets make it even more explicit System.out.println(a() + (b() * c())); } }
If these arguments are evaluated when needed, B or C will come first and the other will be the last However, program output:
a b c 14 a b c 14
Because, regardless of the order of need and use in the equation, they are still evaluated from left to right
Useful reading:
> What are the rules for evaluation order in Java? > a += a++ * a++ * a++ in Java. How does it get evaluated? > Appendix A: Operator Precedence in Java