Perhaps if we write out a method to do the equivalent of what x++
does it will make this clearer.
(Note: this is C# code for the purpose of illustration. Unless I'm mistaken there's actually no way to pass a parameter by reference in Java.)
public static int PostIncrement(ref int x)
{
int valueBeforeIncrement = x;
x = valueBeforeIncrement + 1;
return valueBeforeIncrement;
}
Right? Increment the value passed and return the original value: that's the definition of the postincrement operator.
Now, let's see how this behavior plays out in your example code:
int x = 0;
x = PostIncrement(ref x);
PostIncrement(ref x)
does what? Increments x
, yes. And then returns what x
was before the increment. This return value then gets assigned to x
.
So the order of values assigned to x
is 0, then 1, then 0.
This might be clearer still if we re-write the above:
int x = 0; // x is 0.
int temp = PostIncrement(ref x); // Now x is 1, and temp is 0.
x = temp; // Now x is 0 again.
Your fixation on the fact that when you replace x
on the left side of the above assignment with y
, "you can see that it first increments x, and later attributes it to y" strikes me as confused. It is not x
that is being assigned to y
; it is the value formerly assigned to x
. Really, injecting y
makes things no different from the scenario above; we've simply got:
int x = 0; // x is 0.
int y = 0; // y is 0.
int temp = PostIncrement(ref x); // Now x is 1, and temp is 0.
y = temp; // y is still 0.
So it's clear: x = x++
effectively does not change the value of x. It always causes x to have the values x0, then x0 + 1, and then x0 again.
Update: Incidentally, lest you doubt that x
ever gets assigned to 1 "between" the increment operation and the assignment in the example above, I've thrown together a quick demo to illustrate that this intermediate value does indeed "exist," though it will never be "seen" on the executing thread.
The demo calls x = x++;
in a loop while a separate thread continuously prints the value of x
to the console.
The code is in Java, but I warn you: I have basically zero experience in Java (I only even answered this question because I felt I could explain what was happening with the ++
operator). So this code might be hideous to a seasoned Java developer.
public class Main {
public static volatile int x = 0;
public static void main(String[] args) {
LoopingThread t = new LoopingThread();
System.out.println("Starting background thread...");
t.start();
while (true) {
x = x++;
}
}
}
class LoopingThread extends Thread {
public @Override void run() {
while (true) {
System.out.println(Main.x);
}
}
}
Below is an excerpt of the above program's output. Notice the occasional occurrence of 1 amongst a flurry of 0s.
Starting background thread...
0
0
1
1
0
0
0
0
0
0
0
0
0
0
1
0
1