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

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>