字节码解读:理解变量赋值与自增底层原理

本文详细解释了Java程序执行过程中局部变量表、操作数栈和槽位的作用,以及bipush、istore、iload和iinc等字节码指令的工作原理,通过实例分析了i++和++i的字节码差异。
摘要由CSDN通过智能技术生成

字节码解读

一、基础概念

1、Windows cmd查看程序字节码指令:javap -c
2、局部变量表、操作数栈、槽位
  在Java语言中,任何一个方法执行时,都会专门为这个方法分配所属的内存空间,供这个方法的使用。
  每个方法都有自己独立的内存空间,这个内存空间有两块比较重要的内存空间:局部变量表、操作数栈
  此外,局部变量表中还管理着槽位,在Java虚拟机的线程栈中,局部变量、操作数栈和返回值等数据存储在称为“槽位”的内存单元中。
  每个槽位通常可以容纳一个基本类型值或者是一个引用。
3、bipush、istore、iload、iinc

  • bipush 是 Java 虚拟机(JVM)中的一个字节码指令,用于将一个字节(byte)常量推送到操作数栈顶。

  • istore 是 Java 虚拟机(JVM)中的一个字节码指令,用于将整数类型的值从操作数栈顶存储到局部变量表中的指定位置。

  • iload 是 Java 虚拟机(JVM)中的一个字节码指令,用于将整数类型的值从局部变量表中加载到操作数栈顶。

  • iinc 是 Java 虚拟机(JVM)中的一个字节码指令,用于对局部变量表中的整数值进行增量操作。

二、引例

2.1、局部变量表、操作数栈、槽位、字节码解读(详细)

  • 源码:
public class ReadClass {
    public static void main(String[] args) {
        int i=10;
        int j=i;
        j++;
    }
}
  • 字节码:
Compiled from "ReadClass.java"
public class ReadClass {
    public ReadClass();
    Code:
            0: aload_0
            1: invokespecial #1                  // Method java/lang/Object."<init>":()V
            4: return

    public static void main(java.lang.String[]);
    Code:
            0: bipush        10
            2: istore_1
            3: iload_1
            4: istore_2
            5: iinc          2, 1
            8: return
}
  • 解读:

bipush 10 :将10这个字面量压入操作数栈中。
istore_1 :将操作数栈顶元素弹出,然后将其存储到局部变量表的一号槽位上。
iload_1 :将局部变量表1号槽位上的数据复制一份,压入操作数栈。
istore_2 :将操作数栈顶元素弹出,然后将其存储到局部变量表的二号槽位上。
iinc 2,1 :将局部变量表的2号槽位上的数加一。

2.2、i++、++i字节码角度剖析

  • i++源码:
public class ReadClass1 {
    public static void main(String[] args) {
        int i=10;
        int j=i++;  //先引用i的值,后执行自增操作。
    }
}
  • i++字节码:
Compiled from "ReadClass1.java"
public class ReadClass1 {
    public ReadClass1();
    Code:
            0: aload_0
            1: invokespecial #1                  // Method java/lang/Object."<init>":()V
            4: return

    public static void main(java.lang.String[]);
    Code:
            0: bipush        10     //向操作数栈压入10。
            2: istore_1             //将操作数栈顶元素弹出,然后将其存储到局部变量表的1号槽位上。
            3: iload_1              //将局部变量表1号槽位上的数据复制一份,压入操作数栈。压入的是10。
            4: iinc          1, 1   //将局部变量表的1号槽位上的数加一。  
            7: istore_2             //将操作数栈顶元素弹出,然后将其存储到局部变量表的2号槽位上。
            8: return
  • ++i源码:
public class ReadClass2 {
    public static void main(String[] args) {
        int i=10;
        int j=++i;   //先执行自增操作,后引用i的值。
    }
}
  • ++i字节码:
Compiled from "ReadClass2.java"
public class ReadClass2 {
    public ReadClass2();
    Code:
            0: aload_0
            1: invokespecial #1                  // Method java/lang/Object."<init>":()V
            4: return

    public static void main(java.lang.String[]);
    Code:
            0: bipush        10      //向操作数栈压入10。
            2: istore_1              //将操作数栈顶元素弹出,然后将其存储到局部变量表的1号槽位上。
            3: iinc          1, 1    //将局部变量表的1号槽位上的数加一。 此时一号槽位上的数是11。
            6: iload_1               //将局部变量表1号槽位上的数据复制一份,压入操作数栈。 压入的是11。
            7: istore_2              //将操作数栈顶元素弹出,然后将其存储到局部变量表的2号槽位上。
            8: return


最后欢迎大家踩踩我的博客 Camellia白山茶
  • 8
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值