Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does j += j++ do in Java? [duplicate]

Tags:

java

Can anyone explain this behavior to me?
First, I thought the answer would be 511 + 512 (if j += j++ would mean j = j + (j+1))
How can I justify the answer zero?

public class Test
{
    public static void main(String[] args)
    {
        int i = 0;
        int j = 0;
        for (i = 0, j = 0; i < 10; i++) 
        {
            j += j++;
            System.out.println("i = " + i +  " >> " + j);
        }
        System.out.println(j);
    }
}

> java Test
i = 0 >> 0
i = 1 >> 0
i = 2 >> 0
i = 3 >> 0
i = 4 >> 0
i = 5 >> 0
i = 6 >> 0
i = 7 >> 0
i = 8 >> 0
i = 9 >> 0
0
like image 451
Zeta.Investigator Avatar asked Jun 17 '15 10:06

Zeta.Investigator


3 Answers

Because, the j++, means increment after evaluation, and j+=x means j=j+x so the j becomes j+1 after evaluating j=j+j which is zero( the addition result is 0) after computation of this addition, the j is incremented by j++, but after that the addition result overrides the incremented j value by its value 0.

look at this, let assume j=0;

j += j++

the j++ incrementation will be executed after reading the j value, which is 0 for now.

so it translates into:

   1) read the first value for add operation - the value of j is 0 so we have add(0, ?)
   2) read the second value for add operation `j++` is first evaluated to 0
      so we have now add(0,0), 
      then j is incremented by 1, but it has this value for a very short time:
   3) execute the add(0,0) operation, the result is 0 and overrides the incrementation done in previous setep.
   4) finally the j is 0

So the j becomes a 1 for a very short time in this case, but is overridden very quickly after that.

The conclusion is that mathematically j += j++; finally becomes only j = j + j;

in your for loop this situation repeats every single loop execution, initially the j is 0, so it stays like that forever with blinking to one for a very short time in each loop run.

Maybe you could make the j volatile and then read it in a loop by other thread during evaluation of this j += j++;. The reading thread could probably see that j becomes 1 for a moment, but this is indeterministic, in my case I see this happening using this simple test program:

public class IncrementationTest {

    public static void main(String[] args) {
        new IncrementationTest().start();
    }

    private volatile int j;

    private void start() {
        new Thread() {
            @Override
            public void run() {
                while (true) {
                    System.out.println(j);
                }
            }
        }.start();

        while (true) {
            j += j++;
        }

    }

}

the output is:

...
0
0
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1
0
0
0
...

On my machine it seems to happpen pretty often to have the luck of reading the intermediate 1 for the evaluation of j += j++

like image 122
Krzysztof Cichocki Avatar answered Sep 23 '22 20:09

Krzysztof Cichocki


Because when you do a = b + c you first read b and c and then calculate the values.

Also, j++ means returns the current value of j and then increment it by one.

In your case, since you do j = j + j++ you first read j, then you read j again and returns the value of j. Let's do an example with the first iteration:

  1. You read j = 0
  2. You read j = 0 again
  3. You compute j = j + 1
  4. However, now you compute j = 0 + 0 and override that value

So by the end of the iteration, j's value hasn't changed. It's still 0. That's true for every iteration which is why the value of j never changes.

like image 38
Ori Lentz Avatar answered Sep 24 '22 20:09

Ori Lentz


The issue occurs because 'j++' which if used inside a statement works in the following format -

  1. First the value of j is used inside the statement
  2. Then the value of j is increased.

In your case, when you do j += j++ what happens is -

  1. First the value of j is used inside the statement , is used in the statement, hence j++ returns 0 to be used in the statement, and we have computed 0 + 0 to be assigned to j (not yet assigned) .
  2. The incremented value of j is assigned to j , that is j now becomes 1.
  3. The value computed from Step 1 , which is 0 is assigned to j , hence j becomes 0 again.
like image 21
Anand S Kumar Avatar answered Sep 24 '22 20:09

Anand S Kumar