详讲 i = i ++和 i=++ i 的区别(从字节码的角度解析)

8 篇文章 1 订阅
订阅专栏

java代码如下

public class test {
    public static void main(String[] args) {
        int i=1;
        i=i++;
        System.out.println(i);

        int j=1;
        j=++j;
        System.out.println(j);
    }
}

先提出问题,此时读者认为最后输出的值是什么呢?

我们先不进行解答,先展示一下class反编译之后的文件

public class test {
    public test() {
    }

    public static void main(String[] args) {
        int i = 1;
        int i = i++;
        System.out.println(i);
        int j = 1;
        ++j;
        System.out.println(j);
    }
}

我们可以看到原来的i=i++;操作被替换成了int i=i++;,而j=++j;被替换成了++j;,目前我们根据class文件发现了i=i++和j=++j的直接区别,下面我们将根据字节码进行解释。

main方法的字节码如下(建议文章后续操作都要根据此字节码进行观看)

 0 iconst_1
 1 istore_1
 2 iload_1
 3 iinc 1 by 1
 6 istore_1
 7 getstatic #2 <java/lang/System.out : Ljava/io/PrintStream;>
10 iload_1
11 invokevirtual #3 <java/io/PrintStream.println : (I)V>

--------上面的是i的操作,下面的是j的操作----------

14 iconst_1
15 istore_2
16 iinc 2 by 1
19 iload_2
20 istore_2
21 getstatic #2 <java/lang/System.out : Ljava/io/PrintStream;>
24 iload_2
25 invokevirtual #3 <java/io/PrintStream.println : (I)V>
28 return

我们根据字节码一步一步来解释

前提条件当前局部变量表为

局部变量表
序号012 
元素thisij 
 00 

 

操作数栈(还是空的)

操作数栈
 
 
 
 

 i 值操作过程

1、操作1:iconst_1:将操作数栈放一个int值为1

2、操作2:istore_1:将操作数栈出栈操作,赋值给局部变量表序号为1的元素i,这两部操作相当于我们写的int i=1;操作,如图所示:

 

3、操作3:iload_1:注意此时和++j的操作不一样了,iload_1表示将局部变量表序号为1的元素值执行入栈操作,将值放到操作数栈。

 

 

4、操作4:iinc 1 by 1:表示局部变量表序号1的元素自增加1操作,此时i值为2,具体如图所示:

 5、操作5: istore_1:和操作2一样为出栈操作,将操作数栈的值赋给局部变量表序号为1的元素,也就是说 i 值得变化是从0(初始值)-1-2-1的过程最后为1。如图所示

 i之后的操作就是输出,不过多解释了

j 值操作过程

1、操作1、2: iconst_1  istore_2:和 i 操作1、2一致,就是int j = 1 ;的过程

2、操作3:iinc 2 by 1:注意此时我们和 i 从操作不一样,这时我们是先进行自增操作,也就是说当前局部变量表的 j 值为2了

3、操作4、5:此时我们再次将局部变量表序号为2的元素值放到操作数栈,然后为 j 进行赋值,操作如图

 

 

 最后 i 的值为1,而 j 的值为2

题外话:

有趣的是如果我们不进行输出的操作,无论是 i = i++,还是 j = ++j 都会被class反编译成++i / j,但是在字节码角度上来看又完全不同

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

        int j=1;
        j=++j;
    }
}

class反编译后的文件

public class test {
    public test() {
    }

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

查看这个反编译后的文件,我们竟无法直接查看出  i = i++、 j = ++j 的直接区别,所以贴一下字节码

 0 iconst_1
 1 istore_1
 2 iload_1
 3 iinc 1 by 1
 6 istore_1
 7 iconst_1
 8 istore_2
 9 iinc 2 by 1
12 iload_2
13 istore_2
14 return

在字节码角度来看又有很大的区别,读者可以根据上述的知识自己解析一下~

4万字c++讲解+区分c和c++,不来可惜了(含代码+解析
阿玥的小博客
02-22 1万+
变量声明向编译器保证变量以给定的类型和名称存在,这样编译器在不需要知道变量完整细节的情况下也能继续进一步的编译。可以在 C++ 程序中多次声明一个变量,但变量只能在某个文件、函数或代码块中被定义一次。多个变量赋同一个值时,需要分别赋值。//错误x = y = z;extern 数据类型 变量名;数据类型 变量名1,变量名2,...变量名n;// 变量声明// 变量定义int a, b;// 初始化a = 23;b = 25;return 0;函数类型-函数的返回值类型。
JVM笔记:Java虚拟机的字节码指令详解
verzqli的博客
10-29 1077
1.字节码 Java能发展到现在,其“一次编译,多处运行”的功能功不可没,这里最主要的功劳就是JVM字节码了,在不同平台和操作系统上根据JVM规范的定制JVM可以运行相同字节码(.Class文件),并得到相同的结果。之所以被称之为字节码,是因为字节码文件由十六进制值组成,而JVM以两个十六进制值为一组,即以字节为单位进行读取。在Java中一般是用javac命令编译源代码为字节码文件,将java...
从局部变量表和操作数栈理解 i++++i
whiteBearClimb的博客
02-08 1139
两个概念: 局部变量表:类被创建后的一小块内存区域,存放当前类的局部变量值 操作数栈:栈帧中的一小块内存区域,专门用于存放计算的中间结果值 三个点: 1:赋值操作其实是把操作数栈中的中间结果值进行计算后再赋值给某个变量,是最后一步操作 2: i++ 是指先把i放入操作数栈中,自身局部变量表中的i变量自增+1 3: ++i 是先把局部变量表i的值自增+1,再放入到操作数栈 例子一: 输出的b是多少,应该很多人都知道是1,因为大学时候老师说过a++是先使用a,再++ 但是a因为++了,所以是2 执行过程: (
终于弄明白 i = i++和 i = ++i 了
持续Java学习中
06-09 3万+
写在前面:前些天看完了JVM的内存结构,自以为自己是懂了,心里想想不就是分线程共享和线程私有嘛,然后又怎么怎么分怎么怎么的嘛… 直到遇到了这道题目。说句实话,曾经自己做这种运算题目,完全是靠脑子空想,然后拿上笔颤抖的写下一个自己都不知道正不正确的答案。不过过了今天,我终于能确定它的答案了。 为此,我也专门写一篇博客,记录我的学习!!! 文章目录1、题目2、分析2.1、第一步2.2、第二步2.3、第三步2.4、第四步2.5、结果3、i = ++i 1、题目 package pers.mobian..
正确理解i=i++ i+=i++ i=i++ + i++
gou456654的博客
08-27 695
最近笔试经常能够碰到i=i++的问题,这个问题还是比较简单,不过手贱的自己偏偏想去看看i+=i++,不看不要紧,一看看出了大问题 几个常识 1.result+=expression在所有语言当中都是等价于result=result+expression 2.int i=b++;这个操作是如何完成的呢,首先系统将内存栈中b的值拷贝到寄存器当中,然后将该拷贝值+1 将结果写到a中 步入正题
i = i++和i =++i
cainiao_xiaoniao的博客
01-31 1504
public class Count { public static void main(String[] args) { int i = 0; i = i++ ; System.out.println(i); } } 上面代码输出的i为0,如果是把i = i++换成i=++i,又会输出1,这是由于i++是先赋值,再计算导致,但是为什么先赋值呢? public static void main(String[] args) {
字节码角度解析++
程序猿小河
12-26 425
Java ++、–的操作 ​ ++、–在Java中是一个运算符,目的是对变量自增。++、–在Java中有两种形式。后缀形式,m++、n--;前缀形式,++m,--n。前缀和后缀形式都会讲变量的值+1,但是在表达式中,这两种的用法就有差别了。 1.1 正常的使用 @Test public void test(){ int m = 11; m--; ...
Java 类机制(4)---- 字节码和方法执行
指点
09-30 921
文章目录前言Code 表解析ExceptionTable其他信息方法的执行局部变量表操作数栈动态链接方法返回地址方法返回地址 前言 ​ 大家好,不知不觉已经到 9 月份了,本篇文章是 Java 类机制的最后一篇,我们来一起探讨一下关于 Java字节码和方法调用。本篇文章参考了《深入理解 JVM 虚拟机》一书。 在开始之前我们先回顾一下在之前讲过的内容,在 Java 类机制(3)---- 类文...
Java字节码文件结构剖析-从JVM角度字节码(四)
KingdomCoder
03-14 269
代码案例: public class MyTest1 { private int a = 1; public MyTest1() { } public int getA() { return this.a; } public void setA(int a) { this.a = a; } } 执行命令...
老是自以为JVM懂了,那你知道 i = i++和 i = ++i 的区别吗?
weixin_48674590的博客
07-06 268
前些天看完了JVM的内存结构,自以为自己是懂了,心里想想不就是分线程共享和线程私有嘛,然后又怎么怎么分怎么怎么的嘛… 直到遇到了这道题目。说句实话,曾经自己做这种运算题目,完全是靠脑子空想,然后拿上笔颤抖的写下一个自己都不知道正不正确的答案。不过过了今天,我终于能确定它的答案了。 为此,我也专门写一篇博客,记录我的学习!!! 1、题目 packagepers.mobian.questions01; publicclasstest01{ publicstaticvoidm...
++i i++
zhongjie的专栏
05-28 784
i=i+1 i++ ++I的区别? 请高手解释一下.计算机内部实现过程有别,详细如下:i=i+1的过程相当:  temp=i+1; i=temp;i++的过程相当:  temp=i; i=temp+1; return temp;++i的过程最简单:  i增1然后return i 的值,一步完成,没有给任何temp变量赋值:)
1. i=i++问题解析
c1776167012的博客
12-11 3035
我们都知道CPU每次运算后的值不会直接写到主存中,而是先存放再Cache中再写入主存,这里类似,每条语句的运算结果其实都不会直接赋给那个变量,而是先通过一种中间缓存机制存放,然后赋给相应的变量。在看面试题的时候看到++i和i++的题目,我们都知道他们是加操作先后的差别,但是仔细想想,我们是否真的懂了?可以看到它里面使用了var10000来作为一个中间变量存储i开始的值(10),首先,主方法栈帧初始化内存,然后给i赋值10,给n赋值15。这时,我们是不是能理解为啥i=i++问题了呢?类似的,i=++i;
i++++i分析 (操作数栈)
qq_43663493的博客
08-07 559
什么是操作栈? ​ 操作数栈也被称为操作栈,它是一个后入先出栈。操作数栈中的每一个元素都是包括long和double在内的任意java类型。32位数据类型所栈的栈容量为1,64位数据类型所占的栈容量为2. 当一个方法刚刚开始执行的时候,这个方法的操作数栈是空的 做算术运算的时候是通过将运算涉及的操作数栈压入顶后调用运算指令来进行的,在调用其他的方法的时候是通过操作数栈来进行方法参数来进行值传递的。 自增自减对JVM来说是怎样操作的 在学习中我们一直被告诫,在Java中任何赋值操作都不是原子操作!并且自
JAVA】从原理上分析 i = i++ 与 i = ++i
See_Star的博客
06-09 3472
从原理上(JVM、操作数栈、局部变量表)分析i=i++、i=++i等操作的结果。
i++++i的区别
博客
05-09 996
直接上两个网上很经典的demo 例子1 int i = 1; int j = i++; System.out.println(i); System.out.println(j); 答案:输出2和1 直接反编译class文件,得到前两行的java指令,分析如下 可以看出来,i++分为两iload和iinc,所以j=i++会先将i压入操作数栈,再对变量i自加,所以下一步操作从操作数栈取到的i是自加之前的。 例子2 int i
面试官:你说你懂i++++i的区别,那你会做下面这道题吗?
热门推荐
做一个认真的程序员
04-07 3万+
面试官:你说你懂i++++i的区别,那你会做下面这道题吗? 面试官:“说一说i++++i的区别” 我:“i++是先把i的值拿出来使用,然后再对i+1,++i是先对i+1,然后再去使用i” 面试官:“那你看看下面这段代码,运行结果是什么?” public static void main(String[] args) { int j = 0; for (int i = 0; i ...
Java编程习题解析与建模应用
Java是一种广泛使用的面向对象的编程语言,它具有平台无关性,因为它编译出的字节码可以在任何安装了Java虚拟机(JVM)的操作系统上运行。 Java编程语言的核心是面向对象的概念,这意味着程序的设计和开发都是围绕...
8
原创
9
点赞
24
收藏
4
粉丝
关注
私信
写文章

热门文章

  • gateway转发websocket显示403(Forbidden) 已解决 5401
  • 跨域post请求不携带cookie,前端设置了axios.defaults.withCredentials = true;仍然无法解决 的解决思路 3750
  • 前后端分离项目使用security+JWT处理登录(最新版配置,非WebSecurityConfigurerAdapter 方式配置) 1472
  • 分页插件pagehelper在SpringBoot不起作用的解决办法 1307
  • 前端vue+后端springboot实现页面下载文件 1118

分类专栏

  • java走过的坑 8篇

最新评论

  • 前端vue+后端springboot实现页面下载文件

    博学的刘二胖: 这个应该没有办法监控吧,因为不知道用户是通过什么方式下载

  • 前端vue+后端springboot实现页面下载文件

    良神: 如果想监控用户选了保存还是取消,要怎么做?

  • 前后端分离项目使用security+JWT处理登录(最新版配置,非WebSecurityConfigurerAdapter 方式配置)

    NenoCat: 太强了大佬!

  • gateway转发websocket显示403(Forbidden) 已解决

    CSDN-Ada助手: 不知道 云原生入门 技能树是否可以帮到你:https://edu.csdn.net/skill/cloud_native?utm_source=AI_act_cloud_native

  • 使用opi根据pojo层javadoc注释自动生成excel报表,并通过页面下载(适用场景:数据导出报表页面端下载)

    CSDN-Ada助手: 推荐 Java 技能树:https://edu.csdn.net/skill/java?utm_source=AI_act_java

最新文章

  • 前后端分离项目使用security+JWT处理登录(最新版配置,非WebSecurityConfigurerAdapter 方式配置)
  • gateway转发websocket显示403(Forbidden) 已解决
  • 跨域post请求不携带cookie,前端设置了axios.defaults.withCredentials = true;仍然无法解决 的解决思路
2022年8篇

目录

目录

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值

玻璃钢生产厂家青海佛像玻璃钢雕塑襄阳玻璃钢造型雕塑商场开业美陈图片悬挂商场美陈场景湖北环保玻璃钢雕塑图片西安彩绘玻璃钢雕塑深圳玻璃钢透光雕塑生产厂家浙江个性化玻璃钢雕塑价位玻璃钢花盆一层毡两层布玻璃钢农耕雕塑合肥定制玻璃钢雕塑园林玻璃钢卡通雕塑源头好货四川玻璃钢马雕塑艺术小品天津多彩玻璃钢雕塑优势浦东新区玻璃钢花盆辽源电镀玻璃钢雕塑订做上海进口玻璃钢雕塑省钱玻璃钢卡通雕塑圣诞定做曲阳公园玻璃钢雕塑天津玻璃钢奶牛雕塑玻璃钢花盆雕塑制作河西商场亮化美陈成都商场美陈灯饰萍乡景区玻璃钢雕塑定做价格牡丹江玻璃钢雕塑厂四川玻璃钢雕塑定制价格杭州玻璃钢卡通雕塑厂家推广国内著名玻璃钢雕塑假山企业湖北步行街玻璃钢雕塑供应商营口批发供应沈阳玻璃钢花盆香港通过《维护国家安全条例》两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”19岁小伙救下5人后溺亡 多方发声单亲妈妈陷入热恋 14岁儿子报警汪小菲曝离婚始末遭遇山火的松茸之乡雅江山火三名扑火人员牺牲系谣言何赛飞追着代拍打萧美琴窜访捷克 外交部回应卫健委通报少年有偿捐血浆16次猝死手机成瘾是影响睡眠质量重要因素高校汽车撞人致3死16伤 司机系学生315晚会后胖东来又人满为患了小米汽车超级工厂正式揭幕中国拥有亿元资产的家庭达13.3万户周杰伦一审败诉网易男孩8年未见母亲被告知被遗忘许家印被限制高消费饲养员用铁锨驱打大熊猫被辞退男子被猫抓伤后确诊“猫抓病”特朗普无法缴纳4.54亿美元罚金倪萍分享减重40斤方法联合利华开始重组张家界的山上“长”满了韩国人?张立群任西安交通大学校长杨倩无缘巴黎奥运“重生之我在北大当嫡校长”黑马情侣提车了专访95后高颜值猪保姆考生莫言也上北大硕士复试名单了网友洛杉矶偶遇贾玲专家建议不必谈骨泥色变沉迷短剧的人就像掉进了杀猪盘奥巴马现身唐宁街 黑色着装引猜测七年后宇文玥被薅头发捞上岸事业单位女子向同事水杯投不明物质凯特王妃现身!外出购物视频曝光河南驻马店通报西平中学跳楼事件王树国卸任西安交大校长 师生送别恒大被罚41.75亿到底怎么缴男子被流浪猫绊倒 投喂者赔24万房客欠租失踪 房东直发愁西双版纳热带植物园回应蜉蝣大爆发钱人豪晒法院裁定实锤抄袭外国人感慨凌晨的中国很安全胖东来员工每周单休无小长假白宫:哈马斯三号人物被杀测试车高速逃费 小米:已补缴老人退休金被冒领16年 金额超20万

玻璃钢生产厂家 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化