java字节码

  我们都知道Java字节码是JVM所使用的指令集。java字节码可以分为如下几类:

操作数栈

  Java 方法的栈桢分为操作数栈和局部变量区。通常来说,程序需要将变量从局部变量区加载至操作数栈中,进行一番运算之后再存储回局部变量区中。操作数栈的指令有如下:

  • dup 复制栈顶元素(常用于复制 new 指令所生成的未经初始化的引用。)如下代码生所的字节码:
    java字节码
    dup
  • pop 指令常用于舍弃调用指令的返回结果。当调用了有返回值的方法却不用返回值时需要有个pop指定,如下图所示:
    java字节码
    pop
  • iconst,lconst, fconst, dconst, aconst, bipush, sipush,可以将不同类型的常量加载到操作数栈中。这几个指令的操作范围与类型如下表:
指令 类型 范围
iconst int(boolean, byte, char, short) [-1, 5]
lconst long 0, 1
fconst float 0, 1,2
dconst double 0, 1
dconst reference null
bipush int(boolean, byte, char, short) [-128,127]
sipush int(boolean, byte, char, short) [-32768,32767]

代码与指令的对应关系如下图所示:
java字节码
指令对应图
  • ldc 加载常量池中的常量值。
    java字节码
    Idc加载常量池中的例子
  • 将局部变量区的值加载到操作数栈的指令
      Java 虚拟机将局部变量区当成一个数组,依次存放 this 指针(仅非静态方法),所传入的参数,以及字节码中的局部变量。存储在局部变量区的值,通常需要加载至操作数栈中,方能进行计算,得到计算结果后再存储至局部变量数组中。这些加载、存储指令如下表所示:

类型 加载指令 存储指令
int(boolean, byte, char, short) iload istore
long lload lstore
float fload fstore
double dload dstore
reference aload astore
java字节码
局部变量表的字节码
  • iinc M, N指令,(其中 M为正整数,N为整数),用于操作局部变量区。表求的含义为:将局部变量数组的第 M 个单元中的 int 值增加 N,常用于 for 循环中自增量的更新。字节码如下图所示:
    java字节码
    iinc例子
Java 相关指令
  • new: 后跟目标类,生成该类的未初始化的对象。
  • instanceof:后跟目标类,判断栈顶元素是否为目标类 / 接口的实例。是则压入 1,否则压入 0。如图所示:
    java字节码
    instanceof
  • checkcast:后跟目标类,判断栈顶元素是否为目标类 / 接口的实例。如果不是便抛出异常
  • athrow:将栈顶异常抛出
  • monitorenter/monitorexit 为栈顶对象加解锁。如下图所示:
    java字节码
    monitorenter、monitorexit
  • getstatic、putstatic用于访问静态字段。
  • getfield、putfield用于访问实例子段。
    java字节码
    getfield、getstatic
数组相关指令
  • newarray:新建基本类型数组。
  • anewarray:新建引用类型数组
  • multianewarray :生成多维数组
  • arraylength: 求数组的长度。
    数组相关的加载与存储指令如下表:
类型 加载指令 存储指令
byte(boolean) baload bastore
char caload castore
short saload sastore
int iaload iastore
long laload lastore
float faload fastore
double daload dastore
reference aaload aastore
java字节码
image.png
返回值相关指令

根据不同的返回类型,有不同的指令。如下表所示:

返回类型 返回指令
void return
int(boolean, byte, char, short) ireturn
long lreturn
float freturn
double dreturn
reference areturn
其它
  • goto:无条件跳转指令
  • tableswitch 和 lookupswtich:tableswitch针对密集的 cases,lookupswtich针对稀疏的 cases。


    java字节码
    goto、switch指令