先看这位大哥写的内存原理:
https://blog.csdn.net/bishe_teacher/article/details/107174893
再来看:
int i=1;
i+=++i;
解释:i+=++i相当于i=i+ ++i;
相当于1+ ++1 = 1+2=3;
int i=1;
i+=i++;
解释:i+=++i相当于i=i+ i++;
相当于1+ 1++ = 1+1=2;
问:i++,和++i的运算级高,为什么加完之后没有赋值给第一个i?
答:因为加的时候,从前往后,依次进入栈空间计算,i=i+ ++i时,第一个i此时是1进入栈,第后面的i,自增完后进入栈,再做加法。
举一反三:
int i=1;
i = i + ++i;
int j=1;
j= ++j + j;
System.out.println(i);
System.out.println(j);
i = i + ++i; 1+ ++1 = 1+2=3
j= ++j + j; 2+ 2 = 4 ,后面的j入栈时,已经时第一个j加后的值了。
再看一下javap -c 字节码文件

大概解释一下,可能不太对。自己试试吧。
JVM虚拟机指令
iconst_0:将值为0的int类型推送至栈顶,(0~5通过该指令,-1通过指令iconst_m1)。
istore_1:将栈顶的值存入slot为1,即1号槽位中。
iload_2:将局部变量表2号槽位中的值压入栈顶。
bipush :将单字节常量(-128~127)压入栈顶。
if_icmpge :比较栈顶两个int类型的数值,当前者大于等于后者时跳转。
iinc :完成int类型数值自增自减。
getstatic:获取指定类的静态字段,并将值压入栈顶。
invokevirtual:虚方法调用。
字节码文件命令
编译class
javac Demo.java
查看字节码
javap -c Demo (无需写.class)
Code:
0: iconst_1 将值为1的值推送栈顶,对应i=1
1: istore_1 将栈顶的值存入slot1,对应将i=1存一下
2: iload_1 将局部变量1号槽位压入栈顶,对应++i的i
3: iinc 1, 1 将++i自增,对应++i
6: iload_1 将自增后的值压入栈顶 i=2
7: iadd 执行加法
8: istore_1 将加完的值,存入slot1
9: iconst_1 将值为1的值推送栈顶,对应j=1
10: istore_2 将栈顶的值存入slot2,对应将j=1存一下
11: iinc 2, 1 将++j自增,对应++j
14: iload_2 将局部变量2号槽位压入栈顶,对应++j的j
15: iload_2 将局部变量2号槽位压入栈顶,加号后面的j
16: iadd 执行加法
17: istore_2 将加完的值,存入slot2
18: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
21: iload_1
22: invokevirtual #3; //Method java/io/PrintStream.println:(I)V
25: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
28: iload_2
29: invokevirtual #3; //Method java/io/PrintStream.println:(I)V
32: return
1488

被折叠的 条评论
为什么被折叠?



