i与i的区别
i++
看下面这个案例 int i = 1; i = i++; System.out.println("i = " + i); int j = i++; System.out.println("j = " + j+ ",i = "+ i);
问题: - `System.out.println("i = " + i)` `i` 输出的结果是多少? - `System.out.println("j = " + j+ ",i = "+ i)` `j`和 `i`输出的结果分别是多少?
下面我们看这段代码在jvm中怎么执行的 public static void main(java.lang.String[]) throws java.io.IOException; descriptor: ([Ljava/lang/String;)V flags: ACC_PUBLIC, ACC_STATIC Code: stack=1, locals=3, args_size=1 0: iconst_1 // 常量1入栈 1: istore_1 // 常量1出栈,保存到局部变量表槽点1中 2: iload_1 // 槽点1中的变量i的值入栈 3: iinc 1, 1 // 在局部变量表槽点1中自增1。第一个1是槽点的索引 6: istore_1 // 将指令2中,常量1出栈,保存到局部变量表槽点1中 7: iload_1 // 槽点1中的变量i的值入栈 8: iinc 1, 1 // 在局部变量表槽点1中自增1 11: istore_2 // 将指令7中,常量1出栈,保存到局部变量表槽点2中 12: return LineNumberTable: line 54: 0 line 55: 2 line 56: 7 line 68: 12 LocalVariableTable: Start Length Slot Name Signature 0 13 0 args [Ljava/lang/String; 2 11 1 i I 12 1 2 j I Exceptions: throws java.io.IOException MethodParameters: Name Flags args static {}; descriptor: ()V flags: ACC_STATIC Code: stack=1, locals=0, args_size=0 0: ldc #2 // class com/insuresmart/Test 2: invokestatic #3 // Method org/slf4j/LoggerFactory.getLogger:(Ljava/lang/Class;)Lorg/slf4j/Logger; 5: putstatic #4 // Field log:Lorg/slf4j/Logger; 8: return LineNumberTable: line 18: 0 } SourceFile: "Test.java"int i = 1; i = i++;
对应jvm指令如下 0: iconst_1 // 常量1入栈 1: istore_1 // 常量1出栈,保存到局部变量表槽点1中 2: iload_1 // 槽点1中的变量i的值入栈 3: iinc 1, 1 // 在局部变量表槽点1中的变量i自增1。第一个1是槽点的索引 6: istore_1 // 将指令2中,常量1出栈,保存到局部变量表槽点1中
不难看出 i++ ,在jvm中执行时,先将 i 的值压入栈中,然后在局部变量表中, i 进行自增。
所以上面抛出的问题的答案自然就出来了。 System.out.println("i = " + i) i 输出的结果是多少?i=1 System.out.println("j = " + j+ ",i = "+ i) j 和 i 输出的结果分别是多少?j=1,i=2 ++i
看下面案例 int i = 1; i = ++i; i = i++;
我们看下这段代码在jvm中是怎么执行的 public static void main(java.lang.String[]) throws java.io.IOException; descriptor: ([Ljava/lang/String;)V flags: ACC_PUBLIC, ACC_STATIC Code: stack=1, locals=2, args_size=1 0: iconst_1 // 常量1入栈 1: istore_1 // 出栈,保存到局部变量表中 2: iinc 1, 1 // 局部变量表中,变量i进行自增长 5: iload_1 // 局部变量表中的变量i的值(2)入栈 6: istore_1 //指令5中的数据出栈,保存到局部变量表中 7: iload_1 //局部变量表中的变量i的值(2)入栈 8: iinc 1, 1 // 局部变量表中,变量i进行自增长 11: istore_1 // 指令7中的数据出栈,保存到局部变量表中 12: return int i = 1; i = ++i;
对应jvm指令 0: iconst_1 // 常量1入栈 1: istore_1 // 出栈,保存到局部变量表中 2: iinc 1, 1 // 局部变量表中,变量i进行自增长 5: iload_1 // 局部变量表中的变量i的值(2)入栈 6: istore_1 //指令5中的数据出栈,保存到局部变量表中
++i 是先自增长,再入栈 总结
i++ 和 ++i 执行运算时, i++ 先入栈,再自增 ++i 先自增,再入栈