int i=零; i=i++ System.out.Println(i)
int i0 ii++ System.out.Println(i)?public?class?Test?{ ??????public?static?void?main(String[]?arg
int i=0; i=i++ System.out.Println(i)
?
public?class?Test?{ ??- ????public?static?void?main(String[]?args)?{ ??
- ????????int?i=0; ??
- ????????i=i++; ??
- ????????System.out.println(i); ??
- ????} ??
- } ?
- 结果是0
- 为什么是0 因为:
- 是因为Java编译器的原因:我们来看看编译后的字节码
0 iconst_0 //将int型0推送至栈顶?
1 istore_1 //将栈顶int型数值存入第二个本地变量 i=0 ??(int i=0)
2 iload_1 //将第二个int型本地变量推送至栈顶 ? ? ? ? ? 然后将i推送至栈顶 ? 0
3 iinc 1 1 //将指定int型变量增加指定值(i++, i--, i+=2)完成i++
4 istore_1 //将栈顶int型数值存入第二个本地变量 ? ? ? ?将栈元素赋值给了i ? ?i=0
5 getstatic java/lang/System/out Ljava/io/PrintStream;
6 iload_1
- ?public?static?void?main(String[]?args)?{ ??
- ????????int?i=0; ??
- ? ? ? ??i++; ??
- ????????System.out.println(i); ??
- ????} ?
- 字节码为:
- iconst_0 //将int型0推送至栈顶?
- istore_1 //将栈顶int型数值存入第二个本地变量 i=0 ??(int i=0)
- iinc 1 1 //将指定int型变量增加指定值(i++, i--, i+=2)完成i++
- public?static?void?main(String[]?args)?{ ??
- ????????int?i=0; ??
- ? ? ? ? int k=i++; ??
- ????????System.out.println(i); ??
- ????} ?
- 字节码为:
- 0 iconst_0 //将int型0推送至栈顶?
1 istore_1 //将栈顶int型数值存入第二个本地变量 i=0 ??(int i=0)
2 iload_1 //将第二个int型本地变量推送至栈顶 ? ? ? ? ? 然后将i推送至栈顶 ? 0
3 iinc 1 1 //将指定int型变量增加指定值(i++, i--, i+=2)完成i++
4 istore_2 //将栈顶int型数值存入第三个本地变量 ? ? ? ?将栈元素赋值给了i ? ?i=0
5 getstatic java/lang/System/out Ljava/io/PrintStream;
6 iload_1 - public?static?void?main(String[]?args)?{ ??
- ????????int?i=0; ??
- ? ? ? ? int k=++i; ??
- ????????System.out.println(i); ??
- ????} ?
- 字节码为:
0 iconst_0
1 istore_1
2 iinc 1 by 1
5 iload_1
6 istore_2
- 对比而言,对于i++而言,i=i++指令多了两步,2和4
其实这两步是赋值符号引起的,有意思的是第二步出现的时机,是在iinc之前,这就是因为java lang spec中规定的。 - java编译器对于++i 并不会生成2和4
- int i=0 i=i++ 或者 int i=0 int j= i++ ? ? ?相当于 int temp = i ? ?i++ ? i=temp ? ???int temp = i ? ?i++ ? j=temp
- int i=0 i=++i ? 相当于 ++i ?temp = i ?i=temp;
- 总结:java编译器对于i++会先将i的值保存至另一变量 然后在对i++,另一变量仍没有改变。 而对于++i 是先对i++ 然后保存到另一变量 然后赋值。