【Tips】i++ & ++i不看字节码是真的难懂

package club.interview.base;

/**
 * ++i 先"++"后赋值
 * i++ 先赋值后"++"
 * i++ 局部变量表的值会改变,但是操作数栈并不会变,后面需要使用会把局部变量表中的值放入操作数栈
 * 

* --- 参考内容 (你值得拥有) * * jvms文档 * * jclasslib 工具插件 * * @author QuCheng on 2020/7/6. */ public class IAdd { /** * i++是先赋值后++ ++i是先++后赋值 * 计算机是逐个击破,不是先搜索所有运算法 * 0 iconst_2 * 1 istore_1 * 2 iload_1 栈 [2] * 3 iinc 1 by 1 * 6 iload_1 栈 [3,2] * 7 iadd 栈 [5] * 8 iinc 1 by 1 * 11 iload_1 [4,5] * 12 iadd [9] * 13 iload_1 [4,9] * 14 iadd [13] * 15 istore_1 [] * 16 getstatic #2 * 19 iload_1 [13] * 20 invokevirtual #3 [] * 23 return */ private void sunmmary() { int i = 2; // // 2 3 4 4 i = i++ + i + ++i + i; System.out.println(i); } /** * 局部变量表 -> lvt * 0 iconst_0 将0push到栈顶 * 1 istore_1 将0从栈顶弹出 lvt(index1 = 0) * 2 iinc 1 by 1 栈空 lvt(index1 = 1) * 5 getstatic #2 * 8 iload_1 栈顶为1 lvt(index1 = 1) * 9 invokevirtual #3 * 12 return */ private void step1() { int i = 0; i++; System.out.println(i); } /** * 0 iconst_0 将常量0放入操作数栈栈顶 栈顶为0 * 1 istore_1 将栈顶的int元素赋值给局部变量表第1个位置(弹出)| 栈空 局部变量表index1为0 * 2 iload_1 将局部变量表第1个位置的值push到操作数栈栈顶 | 栈顶为0 局部变量表index1为0 * 3 iinc 1 by 1 将第一个位置的局部变量加1(by 1) | 0-> 1 栈顶为0 局部变量表index1为1 * 6 istore_1 同上(赋值) | 栈空 局部变量表index1为0 (被覆盖) * 7 getstatic #2 * 10 iload_1 读取局部变量1位置到栈顶 | 栈顶为0 局部变量表index1为0 * 11 invokevirtual #3 打印是将局部变量表中的值放入操作数栈栈顶,然后读取 * 14 return */ private void test2() { int i = 0; i = i++; System.out.println(i); } /** * 0 iconst_0 * 1 istore_1 * 2 iload_1 (理解的关键点 把局部变量表中index1位置的值放入栈顶 为了之后赋值) * 3 iinc 1 by 1 * 6 istore_2 lvt(index2 = 0) * 7 getstatic #2 * 10 iload_1 将lvt(index1 = 1) 放入栈顶 * 11 invokevirtual #3 * 14 getstatic #2 * 17 iload_2 将lvt(index2 = 0) 放入栈顶 * 18 invokevirtual #3 * 21 return */ private void step3() { int i = 0; int j; j = i++; System.out.println(i); System.out.println(j); } private void step4() { int i = 0; int j; j = ++i; System.out.println(i); System.out.println(j); } public static void main(String[] args) { IAdd i = new IAdd(); i.sunmmary(); } }

 

你可能感兴趣的:(【Tips】i++ & ++i不看字节码是真的难懂)