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


    package club.interview.base;
    
    /**
     * i = i++; i的值先被放入操作数栈栈顶,++操作是在局部变量表上执行,之后赋值的时候从栈顶获取初始值
    * i = ++i; ++操作先在局部变量表上执行,结果被放入操作数栈栈顶,之后进行赋值操作
    * <p> * --- 参考内容 (你值得拥有) * * jvms文档 * * jclasslib 工具插件 * * @author QuCheng on 2020/7/6.
    */ public class IAdd { /** * 计算机是逐个击破,不是先搜索所有运算法 * 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 <java/lang/System.out> * 19 iload_1 [13] * 20 invokevirtual #3 <java/io/PrintStream.println> [] * 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 <java/lang/System.out> * 8 iload_1 栈顶为1 lvt(index1 = 1) * 9 invokevirtual #3 <java/io/PrintStream.println> * 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 <java/lang/System.out> * 10 iload_1 读取局部变量1位置到栈顶 | 栈顶为0 局部变量表index1为0 * 11 invokevirtual #3 <java/io/PrintStream.println> 打印是将局部变量表中的值放入操作数栈栈顶,然后读取 * 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 <java/lang/System.out> * 10 iload_1 将lvt(index1 = 1) 放入栈顶 * 11 invokevirtual #3 <java/io/PrintStream.println> * 14 getstatic #2 <java/lang/System.out> * 17 iload_2 将lvt(index2 = 0) 放入栈顶 * 18 invokevirtual #3 <java/io/PrintStream.println> * 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(); } }
  • 相关阅读:
    微信小程序反编译
    Mac 绑定Gitlab或者GitHub帐号,从新生成公钥
    Vue调试工具vue-devtools安装及使用
    NPM和Yarn添加淘宝镜像
    权限菜单设计
    Axure RP 7.0注册码
    Mac用户抓包软件Charles 4.0 破解 以及 抓取Https链接设置
    [转]c++导出函数dll供c#调用
    ef(EntityFramework)动态传递数据库连接字符串
    [转]sqlserver查询系统表统计表行数和占用空间
  • 原文地址:https://www.cnblogs.com/nightOfStreet/p/13253792.html
Copyright © 2020-2023  润新知