刚写了个编文章说int i=i++的问题,之后想是iinc指令直接操作本地变量表草成的么,随之用long做了一下实验,看代码和编译后的指令,
public static void iAdd(long i) {
i = i++;
System.out.println(i);
}
变异后的code的第1行的意思是复制栈顶一个(long、double型的)或两个(其它类型的)数值,并且复制值进栈,一直到第2行代码之后,这时候的栈是什么样子的呢?见下图
1 |
1 |
1 |
2 |
1 |
后面的指令是输出语句的编译之后的指令,只做简单分析,6行获取常量池#3指示的静态域压入栈顶,9行加载本地变量表0出的变量到栈顶;
10行栈顶两个元素出栈,调用#4 字符产量指定的函数。最后一行return。
一些个人看法:
i=i++;之所以会出现 执行完不变的情况,是因为:先用再加,按说先用i=i,再加i++;也不会出现不变的情况,应该是,先用,并不是真正的先用,而是在栈中暂时存储,并没有真正给本地变量表的变量赋值,知道i++结束之后,才将之前放入战中的值弹出赋值。
这是i是long的情况下,去掉i=,之后编译后代码,发现少了一个dup2和lstore,也就是少了先用的入栈,和最后的出栈赋值。
另外安利一个比较不错的文章,里面对变异后的指令均做了介绍,帮助甚大。
JVM指令集(指令码、助记符、功能描述) --- 逐渐更新 --- 2011-08-23
(最后又想起来一点,为什么栈的大小是3,因为所有的出栈入栈操作,栈大小为3即可满足所有的入栈出栈操作,最大时为3)