你真的懂i++和++i吗?

  大部分老哥看这篇文章前可能都会认为

                                 i++先赋值再加      

                                ++i加了再赋值         

                                  看了这篇文章后........(先卖个关子)

 

那接下来给老哥上一个题目

照老哥们那样理解这个题目j的值应该为10

按照  i++先赋值再加的思路来分析一遍,

          第一次循环, j++的值为0,先赋值给j,那么j的值就为0,然后再进行j+1那么第一次循环后j的值就为1,

         第二次循环j的值为2

         ......

        第10次循环j的值就为 10

可事情并非向老哥想的那样发展,答案是j的值为0(脑瓜子是不是嗡嗡的)

可能你们会疑惑,难道我以前理解的概念是错的吗?


那我们先从运行时内存方向来分析

        本地方法栈:为虚拟机使用到的Native方法服务

        方法区:存储已经被虚拟机加载的类信息,常量,静态变量

        堆内存:存储对象或者是数组,new出来的都存储在堆内存

        内存(虚拟机栈)方法运行时使用的内存,比如main方法运行,进入方法栈中执行

        程序计数器:记录每个线程执行的位置,用于线程恢复

 我们只需要关注虚拟机栈就好了,每一个线程都有一个自己私有的虚拟机栈,每一个虚拟机栈里面有多个栈帧,每调用一个方法就会为每一个方法生成一个栈帧,每一个栈帧里面都有局部变量表,操作数栈,动态连接,方法返回地址

 

栈内存模型图

 

栈帧

   局部变量表:局部变量值存储空间,用于存储方法参数和方法内部定义的局部变量

   操作数栈:用来存放操作数,局部变量表中的变量是不可以直接使用,需要把局部变量表中的值复制过来再使用

   动态连接

   方法返回地址


再来看以下代码

这个c的值很明显为3,我们通过这个代码和jvm字节码来分析他们在栈帧中是如何运行的

   Ps:在cmd窗口执行 javap  -v  需要获取jvm字节码类名(不需要后缀名), 如:  javap -v  Test  (获取Test类的字节码), 注意:不是java文件是class文件

Ps:具体的jvm字节码指令什么意思可以百度“jvm字节码指令表”

1. inconst_1    ( 将 int 型 1 推送至栈顶)

2. istore_1  (将栈顶 int 型数值存入第二个局部变量,为什么是第二个局部变量呢?因为第一个局部变量为main方法的args参数)

 

3.iconst_2    ( 将 int 型 2 推送至栈顶)

4. iconst_3  (将 int 型 3 推送至栈顶)

 

5.iload_1    ( 将第二个 int 型局部变量推送至栈顶)

6. iload_2  (将第三个 int 型局部变量推送至栈顶)

 

7.iadd( 将栈顶两 int 型数值相加并将结果压入栈顶)

8.istore_3 (将栈顶 int 型数值存入第四个局部变量)

 

9.getstatic( 获取指定类的静态字段,并将其压入栈顶)

10.iload_3 (将第四个 int 型局部变量推送至栈顶)

11.invokevirtual( 调用实例方法)

        这个3步就是执行  “System.out.println(c)”  语句打印c的值

12.return (从当前方法返回 void)


按照这个方法我们再去分析上一个题,j的值为什么是0,先执行  javap -v  Test 命令获取jvm字节码指令

注意看

   10:iload_1  将第二个 int 型局部变量推送至栈顶(把j的值推送到栈顶)

   11: iinc 1, 1   (M为非负整数,N为整数)将局部变量数组的 M个单元中的 int 值增加 N(也就是 j++,执行了这一条jvm指令码,此时j的值已经+1了,但是j++(0)此时还在操作数栈中,还没存入局部变量表,也就是说执行完这一行指令码,操作数栈中的值为0,而此时j的值已经为+1了)

   14: istore_1 将栈顶 int 型数值存入第二个局部变量(这一行最关键,表示执行完这一行指令码的时候,他才吧操作数栈中的值,赋值给j,操作数栈中为0,然后赋值给j,所以j的值又变成0了)

看到这里老哥应该清楚,上一个题目的值j的值为什么为0了吧,


那么接下来给老哥们上一道题,猜猜答案为多少

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值