++操作的坑,细节爬坑

先看一道阿里云大学Java基础自测-初级难度的题

很显然操作顺序先乘2再加1,结果101。GAME OVER!

WTF!结果是100,执手相看结果,竟无语凝噎。

-------------------------------------华丽丽的分割线---------------------------------------------

看看它的背后究竟发生了什么:
1、javac -- $ javac Test.java

             先将这段代码编译成class文件;

2、javap -- $ javap -v -c -l Test.class 

             JDK自带的反解析工具(https://blog.csdn.net/w372426096/article/details/81664431 这篇文章详细介绍了javap的命令)

然后就能看到下面这段执行过程

再来解读一下这个过程,就只看main方法的部分

 大概说下上图中的栈帧:每当线程调用一个Java方法时,JVM就会在该线程对应的栈中压入一个帧,Java中的栈就是由很多栈帧组成的。栈帧由三部分组成:局部变量区、操作数栈、帧数据区。

bipush、istore_1:这两步就是声明一个数值为50,并把它赋值给下标索引为1的变量;

iload_1:将下标索引为1的int变量的值压入栈中;

iinc   1,1:这一步就是说明了++的值去哪了,将指定下标索引的int值+1,这一步的操作并不在栈中,而且有没有赋值我也不清          楚,所以此时的变量值是50还是51?不过这并不影响结果;

iconst_2:将int型的数值2压栈;

imul:栈中的数值相乘;

istore_1:将结果赋值给下标索引为1的变量;

此时变量的值就是100,后面就是调用println方法了。

我勒个去,原来如此啊。。。

-------------------------------------------------------------------------------------------------------

那么~ ++i 为什么会改变值呢?

public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=2, args_size=1
         0: bipush        50
         2: istore_1
         3: iinc          1, 1  //变量自增
         6: iload_1             //增加后的值入栈
         7: istore_1            //再回赋值给变量
         8: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
        11: iload_1
        12: invokevirtual #3                  // Method java/io/PrintStream.println:(I)V
        15: return
      LineNumberTable:
        line 7: 0
        line 8: 3
        line 10: 8
        line 12: 15

现在,你是否明白了呢

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值