Java字节码角度分析a++ ——提升硬实力2

首先建议先看一下基于前面的字节码知识:Java字节码的一段旅行经历——提升硬实力1

在日常的项目开发中,经常遇到a++、++a、a--之类,下面我们开始从字节码的视角来分析a++。

java代码如下:

/*
 从字节码角度分析  a++ 相关题目
 */
public class T03_ByteAnalyseAPlusPlus {
    public static void main(String[] args) {
        int a = 10;
        int b = a++ + ++a + a--;
        System.out.println(a);
        System.out.println(b);
    }
}

使用javap -v xxx.class 来查看类文件全部指令信息:javap -v T03_ByteAnalyseAPlusPlus,如下:

  public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=3, args_size=1
         0: bipush        10
         2: istore_1
         3: iload_1
         4: iinc          1, 1
         7: iinc          1, 1
        10: iload_1
        11: iadd
        12: iload_1
        13: iinc          1, -1
        16: iadd
        17: istore_2
        18: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
        21: iload_1
        22: invokevirtual #3                  // Method java/io/PrintStream.println:(I)V
        25: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
        28: iload_2
        29: invokevirtual #3                  // Method java/io/PrintStream.println:(I)V
        32: return
      LineNumberTable:
        line 17: 0
        line 18: 3
        line 19: 18
        line 20: 25
        line 21: 32
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      33     0  args   [Ljava/lang/String;
            3      30     1     a   I
           18      15     2     b   I
}
SourceFile: "T03_ByteAnalyseAPlusPlus.java"

Process finished with exit code 0

分析:

  • 注意:iinc指令是直接在局部变量槽位slot上进行运算
  • a++ 和 ++a 的区别是先执行 iload 还是先执行 iinc
    • a++是先加载iload,再自增iinc
    • ++a是先自增iinc,再加载iload

下面我们通过字节码来剖析如下两行代码在内存当中整个执行过程

int a = 10;
int b = a++ + ++a + a--;

下图是先将10通过bipush 放入操作数栈中

接着将10从操作数栈上弹出存入局部变量表1号槽位,相当于代码 int a = 10 执行完成

接着执行:int b = a++ + ++a + a--; 因为有从左往右的执行顺序,所以先执行a++,先将a的值加载到操作数栈中;通过iload_1加载1号槽位的数据到操作数栈中

接着执行a++自增1操作,这个操作是在局部变量表中完成的。相当于完成了a++执行

再接着执行++a自增1操作,这个操作也是在局部变量表中完成的

接着从局部变量表1号槽位加载数据到操作数栈中,即12入栈,完成发a++  、++a 各自的执行了

然后,iadd是将操作数栈中弹出(出栈)两个数12、10进行求和操作,得到22,最后将累加的结果22存入栈中。即完成了a++  + +aa的执行

接着,需要执行a--,先将局部变量表槽位1的数据12加载到操作数栈中

然后,将局部变量表槽位1的数据自减1

接着,执行iadd操作,将操作数栈12、22弹出栈后,进行求和操作得到34,再将34结果压入栈

最后,执行istore_2操作,将操作数栈弹出数据34,并压入局部变量表2号槽位中

 


文章最后,给大家推荐一些受欢迎的技术博客链接

  1. Hadoop相关技术博客链接
  2. Spark 核心技术链接
  3. JAVA相关的深度技术博客链接
  4. 超全干货--Flink思维导图,花了3周左右编写、校对
  5. 深入JAVA 的JVM核心原理解决线上各种故障【附案例】
  6. 请谈谈你对volatile的理解?--最近小李子与面试官的一场“硬核较量”
  7. 聊聊RPC通信,经常被问到的一道面试题。源码+笔记,包懂

 


欢迎扫描下方的二维码或 搜索 公众号“10点进修”,我们会有更多、且及时的资料推送给您,欢迎多多交流!

                                           

       

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

不埋雷的探长

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

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

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

打赏作者

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

抵扣说明:

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

余额充值