It is generally believed that the pre-position ++ first adds the value of the variable to 1, and then uses the value after adding 1 to participate in the operation; while the post-position ++ first uses the value to participate in the operation, and then adds the value to 1.
Let’s take a look at the first example:
package test;public class Plus_Test01 { public static void main(String[] args) { int i = 100; i = i++; System.out.println(i); }}Guess what the result is?
Let's look at the second one:
package test;public class Plus_Test02 { public static void main(String[] args) { int k = 100; while (true) { if (k++ > 100) { // System.out.println(k); break; } System.out.println(k); } }}Guess what the result is?
In fact, whether it is pre-++ or post-++, the value of the variable is first increased by 1 before continuing to calculate. The real difference between the two is: the pre-++ adds the value of the variable by 1 and uses the added value to perform calculations, while the post-++ first assigns the variable to a temporary variable, then adds 1 to the value of the variable, and then uses that temporary variable to perform calculations.
For the following code snippet (prefix++):
int i=1;
int j=++i*5;
In fact, the second sentence is equivalent to:
i+=1; //Add i to 1
j=i*5; // Calculate the value after adding 1 with it, the result is: 10
And for the following code snippet (post-++):
int i=1;
int j=i++*5;
The second sentence is equivalent to:
int temp=i; // Assign i to a temporary variable
i+=1; //Add i to 1
j=temp*5; // Calculate the temporary variable with it, the result is: 5
For the first example, it is equivalent to:
int temp=i;
i+=1;
i=temp; //
So the result should be unchanged, that is, 100.
The assembly code for the first example is:
public static void main(java.lang.String[]); descriptor: ([Ljava/lang/String;)V flags: ACC_PUBLIC, ACC_STATIC Code: stack=2, locals=2, args_size=1 0: bipush 100 2: istore_1 3: iload_1 4: iinc 1, 1 // The second one in local var plus 1 7: istore_1 // Save to local var 8: getstatic #16 // Field java/lang/System.out:Ljava/io/PrintStream; 11: iload_1 //The loaded parameter is the second in the stack, that is, it is still 100 12: invokevirtual #22 // Method java/io/PrintStream.println:(I)V 15: return
For the second example, it is actually not difficult, but the result is 101. Pay attention to the process and you can't make such mistakes in the future. (The process is: first compare temp=i, temp>100, obviously does not hold true. Skip i+=1 to the syso sentence, of course, print 101, loop again, and there is also temp=i, temp>100, this time it is true, and then i+=1, jumps out of the loop directly, and the statement in while will not be executed).
Compilation of the second example (only the main method is selected):
public static void main(java.lang.String[]); descriptor: ([Ljava/lang/String;)V flags: ACC_PUBLIC, ACC_STATIC Code: stack=2, locals=2, args_size=1 0: bipush 100 //100 push stack 2: istore_1 //Save to the second local var (the first local var is the method parameter) 3: iload_1 //Load 4 from the second local var: iinc 1, 1 //Increase the int value of the position 2 of local var (the local variable increases, the result is still in the local var, the top 1 of the operand stack will not change) 7: bipush 100 //100 push stack 9: if_icmple 15 //Compare the two int integer values at the top of the operand stack, if the first one is less than or equal to the second one, then jump to line 15 12: goto 25 // Otherwise jump to line 25 (i.e., operand stack top 1> operand stack top 2) 15: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream; 18: iload_1 // //Load from the first local var 19: invokevirtual #3 // Method java/io/PrintStream.println:(I)V //Call this method 22: goto 3 // Jump back to 3 again, loop again 25: return //Exit
The third example:
package test; public class Plus_Test03 { static int proPlus() { int i = 55; int j = ++i; return j; //56 } static int postPlus() { int i = 55; int j = i++; return j; //55 } public static void main(String[] args) { System.out.println(proPlus());//56 System.out.println(postPlus());//55 }}Compilation of the third example:
static int proPlus(); descriptor: ()I flags: ACC_STATIC Code: stack=1, locals=2, args_size=0 0: bipush 55 //55 stack 2: istore_0 //Storage the top of the int stack to the first local var 3: iinc 0, 1 //The first local var plus 1 6: iload_0 //Load from local var 7: istore_1 //Save to the second local var 8: iload_1 //The top of the stack is the second local var 9: ireturnstatic int postPlus(); descriptor: ()I flags: ACC_STATIC Code: stack=1, locals=2, args_size=0 0: bipush 55 2: istore_0 3: iload_0 //Load to stack 4: iinc 0, 1 //The first local var plus 1 7: istore_1 8: iload_1 9: ireturn
It can be seen that the difference between the front ++ and the rear ++ is the blue part above (// the first local var plus 1), which are the opposite. For the predecessor, the number in the local var will be added 1 and then loaded into the stack, while the latter will be loaded from the stack local var to the stack, and then the local var will be added 1, which is equivalent to leaving a backup.
in conclusion:
one. The pre-position and post-position ++ both add 1 to the value of the variable first, instead of adding 1 to the pre-position ++ and then calculating, while the post-position ++ first and then calculating.
two. From a programmatically speaking, the post-++ first assigns the variable to a temporary variable, then adds the value of the variable by 1, and then uses the temporary variable to participate in the operation.
three. From the instruction point of view, the value of the variable is pushed onto the stack before executing the value-added instruction (iinc). After executing the value-added instruction, the value pushed onto the stack is used.
I hope that through this article, I will thoroughly understand the difference between pre-position ++ and post-position ++ operations. Thank you for your support for this site!