I have the following code:
public class Tests {
public static void main(String[] args) throws Exception {
int x = 0;
while(x<3) {
x = x++;
System.out.println(x);
}
}
}
We know he should have writen just x++ or x=x+1, but on x = x++ it should first attribute x to itself, and later increment it. Why does x continue with 0 as value?
–update
Here’s the bytecode:
public class Tests extends java.lang.Object{
public Tests();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]) throws java.lang.Exception;
Code:
0: iconst_0
1: istore_1
2: iload_1
3: iconst_3
4: if_icmpge 22
7: iload_1
8: iinc 1, 1
11: istore_1
12: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
15: iload_1
16: invokevirtual #3; //Method java/io/PrintStream.println:(I)V
19: goto 2
22: return
}
I’ll read about the instructions to try to understand…
Note: Originally I posted C# code in this answer for purposes of illustration, since C# allows you to pass
intparameters by reference with therefkeyword. I’ve decided to update it with actual legal Java code using the firstMutableIntclass I found on Google to sort of approximate whatrefdoes in C#. I can’t really tell if that helps or hurts the answer. I will say that I personally haven’t done all that much Java development; so for all I know there could be much more idiomatic ways to illustrate this point.Perhaps if we write out a method to do the equivalent of what
x++does it will make this clearer.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:
postIncrement(x)does what? Incrementsx, yes. And then returns whatxwas before the increment. This return value then gets assigned tox.So the order of values assigned to
xis 0, then 1, then 0.This might be clearer still if we re-write the above:
Your fixation on the fact that when you replace
xon the left side of the above assignment withy, “you can see that it first increments x, and later attributes it to y” strikes me as confused. It is notxthat is being assigned toy; it is the value formerly assigned tox. Really, injectingymakes things no different from the scenario above; we’ve simply got: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
xever 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 ofxto the console.Below is an excerpt of the above program’s output. Notice the irregular occurrence of both 1s and 0s.