【JVM】从编译后的指令集来再次理解++i和i++的执行顺序

JVM为什么要选用基于栈的指令集架构

  • 与基于寄存器的指令集架构相比,基于栈的指令集架构不依赖于硬件,因此可移植性更好,跨平台性更好
  • 因为栈结构的特性,永远都是先处理栈顶的第一条指令,因此大部分指令都是零地址指令,所以指令集更小
  • 虽然指令集更小,但是同样的一步操作,比基于寄存器所需的指令更多,性能也相对慢

++i的指令集

  • 如下文所示,定义了一段简洁的代码:
public class Demo01 {

    private void test1(){
        int i = 10;
        i = ++i;
    }
}
  • 根据加号在前就等于“先加加再带入计算”的常识,i的结果必然是11
  • 现在再从指令来看到底是经历了什么样的操作才变成了11:
反编译结果如图所示:

在这里插入图片描述

内容和解释如下:
0 bipush 10   --10压入操作数栈
2 istore_1    --将栈顶数字10存入局部变量表索引为1的位置(索引为0的位置放的是this3 iinc 1 by 1 -- *** 将局部变量表中索引为1的位置的数(也就是10)直接加1 ***
6 iload_1     -- *** 将局部变量表中索引为1的位置的数(现在是11)压入操作数栈 ***
7 istore_1    -- *** 将栈顶数字11存入局部变量表索引为1的位置 ***
8 return      --返回11

同时对比一下i++的指令集

  • 如下文所示,定义了一段简洁的代码:
public class Demo01 {

    private void test1(){
        int i = 10;
        i = i++;
    }
}
  • 根据加号在后就等于“先带入计算再加加”的常识,i的结果必然是10
  • 现在再从指令来看到底是经历了什么样的操作才变成了10:
反编译结果如图所示:

在这里插入图片描述

内容和解释如下:
0 bipush 10   --10压入操作数栈
2 istore_1    --将栈顶数字10存入局部变量表索引为1的位置(索引为0的位置放的是this3 iload_1     -- *** 将局部变量表中索引为1的位置的数(现在是10)压入操作数栈 ***
4 iinc 1 by 1 -- *** 将局部变量表中索引为1的位置的数(也就是10)直接加1 ***
7 istore_1    -- *** 将栈顶数字10存入局部变量表索引为1的位置 ***
8 return      --返回10

两种情况的不同之处:
  • 最主要的区别就是图片的红框处以及解释中的星号标注处,i++的时候,读入操作数栈的是没有进行加1的值,而++i的时候,读入操作数栈的是加过1的值
  • ++i的时候是先把局部变量表中的10加成了11,然后把11读取到操作数栈,然后再覆盖回局部变量表,所以最后返回了11
  • i++的时候是把10读取到了操作数栈,然后把局部变量表中的10加成了11,但是下一步又用操作数栈的10 覆盖了局部变量表中的11,所以最后返回了10

相关推荐

  1. 0115__i++循环与i--循环执行效率

    2024-06-10 19:56:01       11 阅读
  2. ++i(前置自增) i++(置自增)区别

    2024-06-10 19:56:01       25 阅读
  3. RV32I指令

    2024-06-10 19:56:01       8 阅读
  4. I/O密集型任务CPU密集型任务理解与对比

    2024-06-10 19:56:01       16 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-06-10 19:56:01       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-06-10 19:56:01       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-06-10 19:56:01       19 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-06-10 19:56:01       20 阅读

热门阅读

  1. 力扣395.至少有K个重复字符的最长子串

    2024-06-10 19:56:01       8 阅读
  2. next.js 的几种渲染方式

    2024-06-10 19:56:01       6 阅读
  3. RAG技术在教育领域的应用

    2024-06-10 19:56:01       11 阅读
  4. 关于使用spring boot自带的jackson解析xml心得

    2024-06-10 19:56:01       9 阅读
  5. 第8天:会话管理与Cookies

    2024-06-10 19:56:01       8 阅读
  6. selenium中,如何使用选择框

    2024-06-10 19:56:01       10 阅读
  7. 1、深度学习-安装

    2024-06-10 19:56:01       11 阅读
  8. 【RFC3665】SIP协议解析

    2024-06-10 19:56:01       8 阅读
  9. 机器学习(一)

    2024-06-10 19:56:01       8 阅读