欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 健康 > 美食 > JVM 常用字节码指令有哪些?

JVM 常用字节码指令有哪些?

2025/4/13 3:46:34 来源:https://blog.csdn.net/nmsoftklb/article/details/146158970  浏览:    关键词:JVM 常用字节码指令有哪些?

JVM 字节码指令集非常庞大,包含了大量的指令来完成各种操作。 我们只需要掌握一些常用的字节码指令即可。

以下是一些最常用、最核心的 JVM 字节码指令,按照功能类别进行划分:

1. 操作数栈 (Operand Stack) 操作指令:

  • nop (No Operation): 什么也不做,空指令,通常用于调试或占位。
  • aconst_null (Push null):null 引用值推送到操作数栈顶。
  • iconst_m1, iconst_0, iconst_1, iconst_2, iconst_3, iconst_4, iconst_5 (Push int constant):int 型常量 -1, 0, 1, 2, 3, 4, 5 推送到操作数栈顶。
  • fconst_0, fconst_1, fconst_2 (Push float constant):float 型常量 0.0f, 1.0f, 2.0f 推送到操作数栈顶。
  • dconst_0, dconst_1 (Push double constant):double 型常量 0.0d, 1.0d 推送到操作数栈顶。
  • lconst_0, lconst_1 (Push long constant):long 型常量 0L, 1L 推送到操作数栈顶。
  • bipush <b> (Push byte):byte 型常量 <b> 推送到操作数栈顶。
  • sipush <s> (Push short):short 型常量 <s> 推送到操作数栈顶。
  • ldc <index> (Load constant):常量池中加载 int, float, String 类型常量或类引用推送到操作数栈顶。
  • ldc_w <index> (Load constant wide): 宽索引版本 ldc,用于加载常量池索引范围更大的常量。
  • ldc2_w <index> (Load constant wide 2): 从常量池中加载 longdouble 类型常量推送到操作数栈顶 (占用两个栈槽)。
  • pop (Pop top operand stack value): 将栈顶数值弹出 (通常用于丢弃不需要的计算结果)。
  • pop2 (Pop top 2 operand stack values): 将栈顶两个数值弹出 (用于 longdouble 类型,或两个非 longdouble 类型的值)。
  • dup (Duplicate top operand stack value): 复制栈顶数值,并将副本压入栈顶。
  • dup_x1 (Duplicate top operand stack value and insert below): 复制栈顶数值,并将副本插入到栈顶数值之下。
  • dup_x2 (Duplicate top operand stack value and insert two values down): 复制栈顶数值,并将副本插入到栈顶数值之下两个位置。
  • dup2 (Duplicate top 1 or 2 operand stack values): 复制栈顶一个或两个数值,并将副本压入栈顶 (用于 longdouble 或两个非 longdouble 类型的值)。
  • dup2_x1 (Duplicate top 1 or 2 operand stack values and insert below): 复制栈顶一个或两个数值,并将副本插入到栈顶数值之下。
  • dup2_x2 (Duplicate top 1 or 2 operand stack values and insert two values down): 复制栈顶一个或两个数值,并将副本插入到栈顶数值之下两个位置。
  • swap (Swap top two operand stack values): 交换栈顶两个数值。

2. 局部变量表 (Local Variable Table) 访问指令:

  • iload <index>, fload <index>, aload <index>, lload <index>, dload <index> (Load from local variable): 将指定索引的 int, float, reference, long, double 型局部变量加载到操作数栈顶。
  • iload_0, iload_1, iload_2, iload_3 (Load int from local variable 0-3): 加载索引为 0, 1, 2, 3int 型局部变量到栈顶 (更高效的指令)。
  • fload_0, fload_1, fload_2, fload_3 (Load float from local variable 0-3): 加载索引为 0, 1, 2, 3float 型局部变量到栈顶。
  • aload_0, aload_1, aload_2, aload_3 (Load reference from local variable 0-3): 加载索引为 0, 1, 2, 3reference 型局部变量到栈顶 (例如 this 引用通常在索引 0)。
  • lload_0, lload_1, lload_2, lload_3 (Load long from local variable 0-3): 加载索引为 0, 1, 2, 3long 型局部变量到栈顶。
  • dload_0, dload_1, dload_2, dload_3 (Load double from local variable 0-3): 加载索引为 0, 1, 2, 3double 型局部变量到栈顶。
  • istore <index>, fstore <index>, astore <index>, lstore <index>, dstore <index> (Store into local variable): 将栈顶的 int, float, reference, long, double 型数值存储到指定索引的局部变量。
  • istore_0, istore_1, istore_2, istore_3 (Store int into local variable 0-3): 将栈顶 int 型数值存储到索引为 0, 1, 2, 3 的局部变量 (更高效的指令)。
  • fstore_0, fstore_1, fstore_2, fstore_3 (Store float into local variable 0-3): 将栈顶 float 型数值存储到索引为 0, 1, 2, 3 的局部变量。
  • astore_0, astore_1, astore_2, astore_3 (Store reference into local variable 0-3): 将栈顶 reference 型数值存储到索引为 0, 1, 2, 3 的局部变量。
  • lstore_0, lstore_1, lstore_2, lstore_3 (Store long into local variable 0-3): 将栈顶 long 型数值存储到索引为 0, 1, 2, 3 的局部变量。
  • dstore_0, dstore_1, dstore_2, dstore_3 (Store double into local variable 0-3): 将栈顶 double 型数值存储到索引为 0, 1, 2, 3 的局部变量。

3. 运算指令:

  • 算术运算:
    • iadd, fadd, dadd, ladd (加法)
    • isub, fsub, dsub, lsub (减法)
    • imul, fmul, dmul, lmul (乘法)
    • idiv, fdiv, ddiv, ldiv (除法)
    • irem, frem, drem, lrem (求余数)
    • ineg, fneg, dneg, lneg (取反)
    • ishl, lshl (左移)
    • ishr, lshr (算术右移)
    • iushr, lushr (逻辑右移)
    • iand, land (按位与)
    • ior, lor (按位或)
    • ixor, lxor (按位异或)
    • iinc <index> <const> (int 变量自增,局部变量表操作)
  • 类型转换:
    • i2b, i2c, i2s (int 转 byte, char, short)
    • i2l, i2f, i2d (int 转 long, float, double)
    • l2i, l2f, l2d (long 转 int, float, double)
    • f2i, f2l, f2d (float 转 int, long, double)
    • d2i, d2l, d2f (double 转 int, long, float)
  • 比较:
    • lcmp (long 比较)
    • fcmpl, fcmpg (float 比较,l 表示 NaN 时结果为 -1,g 表示 NaN 时结果为 1)
    • dcmpl, dcmpg (double 比较,l 表示 NaN 时结果为 -1,g 表示 NaN 时结果为 1)

4. 类型转换和检查指令:

  • checkcast <class> (Check whether object is of given type): 检查对象是否是指定类型,如果是则继续,否则抛出 ClassCastException
  • instanceof <class> (Determine if object is of given type): 检查对象是否是指定类型的实例,结果 (10) 推送到操作数栈顶。

5. 对象操作指令:

  • new <class> (Create new object): 创建一个对象,但不初始化,只在堆上分配空间,并将未初始化的对象引用推送到操作数栈顶。
  • anewarray <component type> (Create new array of references): 创建一个指定组件类型的引用类型数组,数组长度从操作数栈弹出。
  • newarray <atype> (Create new array of primitive type): 创建一个指定基本类型的基本类型数组,数组长度从操作数栈弹出 (例如 int, boolean, char 等)。
  • arraylength (Get length of array): 获取数组长度,数组引用从操作数栈弹出,数组长度推送到栈顶。
  • aaload, baload, caload, saload, iaload, laload, faload, daload (Load from array): 从数组中加载元素,数组引用和索引从操作数栈弹出,加载的元素值推送到栈顶 (对应 reference, byte, char, short, int, long, float, double 类型)。
  • aastore, bastore, castore, sastore, iastore, lastore, fastore, dastore (Store into array): 将值存储到数组中,数组引用、索引和要存储的值从操作数栈弹出 (对应 reference, byte, char, short, int, long, float, double 类型)。
  • getfield <field> (Fetch field from object): 获取对象的实例字段的值,对象引用从操作数栈弹出,字段值推送到栈顶。
  • putfield <field> (Set field in object): 设置对象的实例字段的值,对象引用和要设置的字段值从操作数栈弹出。
  • getstatic <field> (Get static field from class): 获取类的静态字段的值,字段值推送到操作数栈顶。
  • putstatic <field> (Set static field in class): 设置类的静态字段的值,要设置的字段值从操作数栈弹出。

6. 方法调用和返回指令:

  • invokevirtual <method> (Invoke virtual method): 调用对象的虚方法 (运行时多态)。
  • invokespecial <method> (Invoke instance method; special handling): 调用实例方法,但需要特殊处理的情况,例如:
    • 调用父类方法 (super.method())
    • 调用私有方法
    • 调用构造器 (<init>)
  • invokestatic <method> (Invoke a class (static) method): 调用静态方法
  • invokeinterface <interface method> (Invoke interface method): 调用接口方法
  • invokedynamic <method> (Invoke dynamic method): 用于支持动态语言特性,例如 Lambda 表达式、动态代理等 (JDK 7 新增)。
  • ireturn, freturn, areturn, lreturn, dreturn (Return from method): 从方法返回,并将栈顶的 int, float, reference, long, double 类型值作为返回值返回。
  • return (Return void from method):void 方法返回。

7. 控制流指令:

  • 条件跳转:
    • ifeq <branchoffset> (If int compare with zero is equal branch): 如果栈顶 int 型数值等于 0,则跳转。
    • ifne <branchoffset> (If int compare with zero is not equal branch): 如果栈顶 int 型数值不等于 0,则跳转。
    • iflt <branchoffset> (If int compare with zero is less than branch): 如果栈顶 int 型数值小于 0,则跳转。
    • ifge <branchoffset> (If int compare with zero is greater than or equal branch): 如果栈顶 int 型数值大于等于 0,则跳转。
    • ifgt <branchoffset> (If int compare with zero is greater than branch): 如果栈顶 int 型数值大于 0,则跳转。
    • ifle <branchoffset> (If int compare with zero is less than or equal branch): 如果栈顶 int 型数值小于等于 0,则跳转。
    • if_icmpeq <branchoffset> (If int compare equal branch): 如果栈顶两个 int 型数值相等,则跳转。
    • if_icmpne <branchoffset> (If int compare not equal branch): 如果栈顶两个 int 型数值不相等,则跳转。
    • if_icmplt <branchoffset> (If int compare less than branch): 如果栈顶第一个 int 型数值小于第二个,则跳转。
    • if_icmpge <branchoffset> (If int compare greater than or equal branch): 如果栈顶第一个 int 型数值大于等于第二个,则跳转。
    • if_icmpgt <branchoffset> (If int compare greater than branch): 如果栈顶第一个 int 型数值大于第二个,则跳转。
    • if_icmple <branchoffset> (If int compare less than or equal branch): 如果栈顶第一个 int 型数值小于等于第二个,则跳转。
    • ifnull <branchoffset> (If reference is null branch): 如果栈顶 reference 型数值为 null,则跳转。
    • ifnonnull <branchoffset> (If reference is not null branch): 如果栈顶 reference 型数值不为 null,则跳转。
  • 无条件跳转:
    • goto <branchoffset> (Branch always): 无条件跳转到指定偏移量。
    • goto_w <branchoffset> (Branch always wide): 宽偏移量版本 goto,用于跳转范围更大的情况。
  • tableswitch (Access jump table by index and jump): 用于 switch 语句 (当 case 值连续时)。
  • lookupswitch (Access jump table by key match and jump): 用于 switch 语句 (当 case 值不连续时)。

8. 异常处理指令:

  • athrow (Throw exception or error): 将栈顶的异常对象抛出。
  • checkcast <class> (Check whether object is of given type): 检查对象类型,如果类型不匹配,抛出 ClassCastException (也可以用于类型检查,不仅仅是异常处理)。
  • monitorenter (Enter monitor for object): 尝试获取对象的 monitor (锁),用于 synchronized 关键字的同步块的开始。
  • monitorexit (Exit monitor for object): 释放对象的 monitor (锁),用于 synchronized 关键字的同步块的结束。

类型缩写:

在指令助记符中,通常会使用一些类型缩写来表示操作的数据类型:

  • i: int
  • l: long
  • f: float
  • d: double
  • a: reference (对象引用)
  • b: byte
  • c: char
  • s: short

学习建议:

  • 无需记住所有指令: 字节码指令数量庞大,不需要全部记住,重点掌握常用的指令和它们的功能。
  • 结合实例学习: 通过查看 Java 代码编译后的字节码,结合具体的代码示例来学习指令,更容易理解。可以使用 javap -c <类名> 命令反编译 .class 文件查看字节码。
  • 关注指令类别: 按照功能类别 (操作数栈、局部变量表、运算、控制流等) 来学习,更容易形成体系。
  • 查阅 JVM 规范: 如果需要深入了解某个指令的细节,可以查阅 JVM 规范 (The Java Virtual Machine Specification)。
  • 理解 JVM 的基本执行模型: 基于栈的指令集、操作数栈、局部变量表等。
  • 分析 Java 代码的性能: 通过分析字节码,可以了解代码的执行效率,找出潜在的性能瓶颈。
  • 进行更深层次的 Java 调优: 理解字节码优化,可以编写更高效的 Java 代码。
  • 深入理解 Java 语言特性: 例如,多态、异常处理、同步机制等在字节码层面的实现。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词