对于i++和++i的深入理解

在学完jvm的一些知识后,发现有些令人云山雾罩的问题,逐渐变得条理清晰。首先,在这里保证,看完以下解释,让你彻底明白i++和++i的原理,而不是停留在先赋值后运算的浅层次的理解。因为涉及底层,有些东西可能晦涩难懂,但难能可贵。但柳岸花明又一村,相信你可以。加油。

一、相关知识

以下介绍的知识是理解的必备装备,在打“boss”前最后还是捡一些武器。

虚拟机栈:java虚拟机运行时数据区的一部分,一个线程对应一个栈,栈控制着方法的调用。
栈帧:虚拟机栈的栈元素,每次调用一个方法,就会创建与方法对应的栈帧,并将栈帧入栈。
举个栗子:

public class Main {
    public static void main(String[] args) {
        int i = 1;
        int j = i++;
    }
}

在这里插入图片描述

栈帧结构(详细内容参阅:http://www.cnblogs.com/noKing/p/8167700.html)

局部变量表: 是一片逻辑连续的内存空间,可以理解为类似数组的结构,具有像slot0、slot1这样的索引。它是用来存放方法参数和方法内部定义的局部变量。
是按参数和局部变量在代码中出现的顺序而依次对应slot0、slot1、
slot2的存储位置,为了更直观写了slot0(args),实际只有索引slot0,没有args。

知识拓展slot:slot是虚拟机为局部变量表分配内存所使用的最小单位。对于byte,char,float,int,shot,boolean,reference和returnAddress等长度不超过32位的数据类型,每个局部变量占1个Slot,而double与long这两种64位的数据类型而需要2个Slot来存放

操作数栈: Java虚拟机提供指令来让操作数栈对一些数据进行入栈操作,比如可以把局部变量表里的数据、实例的字段、常量值等数据入栈。

栈帧的大小在编译时就确定,局部变量表的大小、操作数栈的大小也是在编译时就确定大小的。

二、底层执行过程

(1) 反编译得到main方法对应的字节码指令

cmd(windows命令行):javap -v Main.class
在这里插入图片描述
(注:stack即操作数栈,locals即局部变量表)

接下来我们依次运行八条指令,索引是从0开始的。

以下大多数情况i开头的i代表int类型
0: iconst_1 将int型常量值1入操作数栈
在这里插入图片描述


1: istore_1   出栈(操作数栈),并把出栈的值保存到局部变量表索引为1(从_1得知索引为1)的位置
在这里插入图片描述

2:iload_1   将索引为1即slot1处的值拷贝一份入栈
在这里插入图片描述
3: iinc 1, 1   *将索引为slot1处的值 加1
iinc index, constvalue
index:由执行++运算的变量在局部变量表的位置决定,本测试中为i++,而i对应的局部变量表的位置为slot1,所以index=1.
contstvalue: 由于++运算为变量加1,所以constvalue恒为一.

在这里插入图片描述
6: istore_2   出栈,并把值保存到索引值为2即slot2处
在这里插入图片描述

int i = 1 ;
int j = i++;

最终执行结果: i = 2; j=1;
7: return    方法执行完毕,对应栈帧出栈
在这里插入图片描述


那么 ++i是如何进行的呢?

Main.java

public class Main {
    public static void main(String[] args) {
        int i = 1;
        int j = ++i;
    }
}

字节码指令
在这里插入图片描述

执行流程:
在这里插入图片描述

看到这里,参不多已经可以下山了。没有一点小激动吗?别急,临走前,在给你本“葵花宝典”!
《葵花宝典》–对比图
在这里插入图片描述


写在结尾:纯手工制作,没有复制粘贴。您的赞是对我最大的鼓励!

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

明月几时有666

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值