为了讲解i++与++i,直接由以下几个例子分析:
例子一
-
方法test1()和test2()字节码解释:当直接使用i++与++i的时候,反编译字节码文件是一致的,均为
0 iconst_1 //立即数 1 压入操作数栈 1 istore_1 //栈顶元素 1 写入到局部变量表索引为1的位置 2 iinc 1 by 1 //局部变量表索引为1的数 +1 即 1+1 = 2 5 return
由此可以得出,执行结果后,局部变量表中的变量 i 为2。
例子二
- 方法test3()字节码解释:i++赋值给i时,经历了先从局部变量表中数据(i=1)放入到操作数栈中(i=1),然后局部变量表当前变量+1(即i=2),之后将栈顶元素写入到局部变量表中(1覆盖了原来的2),所以最后结果为1!
- 方法test4()字节码解释:++i赋值给i时,局部变量表当前变量+1(即i=2),然后放入到操作数栈中(i=2),之后将栈顶元素写入到局部变量表中(2–>2),所以最后结果为2!
区别:
- i++是先入栈再加1,栈中元素在写回局部变量表!
- ++i是先加1再入栈,栈中元素在写回局部变量表!
例子三
- 方法test5()和test6()字节码解释:如图,注释写的应该比较清晰。
总结
- 只需记住i++是先入栈再加1,++i是先加1再入栈,在进行计算时,可以画图加深理解。
- 补充:每个线程都有自己的栈,线程中的每个方法都有自己的栈桢,栈桢中存储着局部变量表,操作数栈,动态链接,方法返回地址以及一些附加信息;栈桢的大小主要是由局部变量表和操作数栈决定。
JMM内存交互操作
内存交互操作有8种,虚拟机实现必须保证每一个操作都是原子的、不可再分的(对于double和long类型的变量来说,load、store、read和write操作在某些平台上允许例外)
- lock (锁定):作用于主内存的变量,把一个变量标识为线程独占状态;
- unlock (解锁):作用于主内存的变量,它把一个处于锁定状态的变量释放出来,释放后的变量才可以被其它线程锁定;
- read (读取):作用于主内存变量,它把一个变量的值从主内存传输到线程的工作内存中,以便随后的load动作使用;
- load (载入):作用于工作内存的变量,它把read操作从主存中变量放入工作内存中;
- use (使用):作用于工作内存中的变量,它把工作内存中的变量传输给执行引擎,每当虚拟机遇到一个需要使用到变量的值,就会使用到这个指令;
- assign (赋值):作用于工作内存中的变量,它把一个从执行引擎中接受到的值放入工作内存的变量副本中;
- store (存储):作用于工作内存中的变量,它把一个从工作内存中一个变量的值传送到主内存中,以便后续的write使用;
- write(写入):作用于主内存中的变量,它把store操作从工作内存中得到的变量的值放入主内存的变量中。
原创不易,欢迎转载,转载时请注明出处,谢谢!