预备知识:
首先要说的是每个现在都有独立的栈空间,然后在单个线程中会对每一个方法分配一个栈帧内存,当分配栈帧内存的时候同时也会分配局部变量表以及操作数栈。++这个操作时在本地变量表的槽位上进行计算的 而+是在操作数栈内进行相加的,a++ 和 ++a 的区别是先执行 iload(读入操作数栈) 还是 先执行 iinc(自增)
题目:
int a = 10;
int b = a++ + ++a + a--;
System.out.println(a);
System.out.println(b);
对应的字节码指令:
代码结合字节码说明(如果此处还看不懂就看下面的图解)
int a = 10;
// 0: bipush 10 首先,先将10 压入操作数栈中
// 2: istore_1 然后把它存到本地变量表1号槽位 a=10
int b = a++ + ++a + a--;
// 3: iload_1 从本地变量表1号槽位中读取到操作数栈中 10
// 4: iinc 1, 1 本地变量表1号槽位中的数自增1 为11
// 7: iinc 1, 1 本地变量表1号槽位中的数自增1 为12
// 10: iload_1 将本地变量表1号槽位中的数读到操作数栈中 12
// 11: iadd 将操作数栈中的数进行相加 10+12 ,相加之后10 与 12 便出栈,然后将结果22压入栈顶
// 12: iload_1 将本地变量表1号槽位中的数入读操作数栈中 为12
// 13: iinc 1, -1 本地变量表1号槽做自减1
// 16: iadd 将操作数栈中的数进行相加 22+12,相加之后22与12出栈,然后将结果34压入栈中
// 17: istore_2 将34存入本地变量表2号槽位中
System.out.println(a);
System.out.println(b);
图解
1 int a = 10;
1.1 先将10压入操作数栈中
1.2 将10写入本地变量表1号槽位,然后将10出栈

2、int b = a++ + ++a + a--;
2.1.1 此时先实现a++,++符号在后,表示先将a的值读入操作数栈中,在进行自增,此时先将a=10读入操作数栈中
2.1.2 在将a读入操作数栈后,对本地变量表1号槽位的数进行自增,这个过程发生在1号槽位,不涉及操作数栈,此时用于计算的操作数栈中的值为10,而本地变量表1号槽位的值为11
2.2.1 此时实现++a,++符号在前表示先在本地变量表中对a自增,然后再将自增后的值读入操作数栈中 ,自增后a为12
2.2.2 将自增后的结果12读入操作数栈中
2.3 实现+操作(a++)+(++a) ,将操作栈中的值进行相加之后,将12,10都弹出操作数栈,然后将结果值22压入操作数栈
2.4.1 此时实现a--,--在后面表示先将a的值读入操作数栈后再在本地变量表槽位上自减,不涉及操作数栈,将a读入操作数栈后,操作数栈中有12与22(上一次相加的结果)
2.4.2 在a读入操作数栈之后,在本地变量表1号槽位进行自减
2.5 执行+操作(a++)+(++a)+ (a--)将12和22进行相加,然后将12与22弹出操作数栈,将结果34压入操作数栈
2.6 将34 存入本地变量表2号槽位 ,并将操作数栈中的数弹出