字节码是JVM所使用的指令集。
在执行每一条指令前,JVM要求该指令的操作数已被压入操作数栈中;
在执行指令时,JVM会将该指令所需要的操作数弹出,并将指令的结果重新压入栈中。
- dup(dup2) : 复制栈顶单元(dup2:long或者double类型需要占两个栈单元)
- pop(pop2) : 弹出栈顶单元(pop2:long或者double类型需要占两个栈单元)
- swap : 交换栈顶两个元素的值
直接将常量加载到操作数栈上(常量加载指令表)
类型 | 常数指令 | 范围 |
---|---|---|
int (boolean,byte,char,short) | iconst | [-1, 5] |
bipush | [-128, 127] | |
sipush | [-32768, 32767] | |
ldc | any int value | |
long | lconst | 0, 1 |
ldc | any long value | |
float | fconst | 0, 1, 2 |
ldc | any float value | |
double | dconst | 0, 1 |
ldc | any double value | |
reference | aconst | null |
ldc | String literal, Class literal |
正常情况下,操作数栈的压入弹出是一条条指令完成的;
唯一例外的情况是:抛异常时,JVM会清除操作数栈上的所有内容,然后将异常实例压入操作数栈
字节码程序可以将计算的结果缓存在局部变量区中;
JVM将局部变量区当做数组,依次存入this指针(非静态方法),方法所传入的参数,以及字节码中的局部变量
存储在局部变量区的值,通常需要加载到操作数栈,方能参与计算,得到计算结果后,再存储到局部变量数组中。
局部变量区指令表:
类型 | 加载指令(局部变量变区->操作数栈) | 存储指令(操作数栈->局部变量变区) |
---|---|---|
int(boolean,byte,char,short) | iload | istore |
long | lload | lstore |
float | fload | fstore |
double | dload | dstore |
reference | aload | astore |
局部变量数组的加载,都必须指明加载单元的下标: aload 0 指加载第0个单元所存储的引用
指令 | 作用 | 示例(描述) |
---|---|---|
new | 后跟目标类,生成该类的未初始化对象 | |
instanceof | 后跟目标类,判断栈顶元素是否为目标类/接口的实例,是则压入1,否则压入0 | |
checkcast | 后跟目标类,判断栈顶元素是否为目标类/接口的实例,不是则抛异常 | |
athrow | 将栈顶异常抛出 | |
monitorenter | 为栈顶对象加锁 | |
monitorexit | 为栈顶对象解锁 | |
字段访问: | ||
getstatic | 获取静态字段的值 | |
putstatic | 将值存储到静态字段中 | |
getfield | 获取实例字段的值 | |
putfield | 将值存储到实例字段中 | |
方法调用: | ||
invokestatic | 用于调用静态方法 | 1. 不需要压入调用者 2. 消耗操作数栈元素是根据调用类型和目标方法描述符来确定的 |
invokespecial | 用于调用私有实例方法、构造器、使用super关键字调用父类的实例方法或构造器,和所实现接口的默认方法 | 1. 消耗操作数栈元素是根据调用类型和目标方法描述符来确定的 |
invokevirtual | 用于调用非私有实例方法 | 1. 消耗操作数栈元素是根据调用类型和目标方法描述符来确定的 |
invokeinterface | 用于调用接口方法 | 1. 消耗操作数栈元素是根据调用类型和目标方法描述符来确定的 |
invokedynamic | 用于调用动态方法 | 比较复杂 |
指令 | 作用 | 示例(描述) |
---|---|---|
新建: | ||
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 |
指令 | 作用 | 示例(描述) |
---|---|---|
goto | 无条件跳转 | |
tableswitch | 针对密集型cases | |
lookupswitch | 针对稀疏型cases | |
返回指令: | ||
数据类型 | 返回指令 | |
void | return | |
int(boolean,byte,char,short) | ireturn | |
long | lreturn | |
float | freturn | |
double | dreturn | |
reference | areturn |
除返回指令外,其他控制流指令均附带一个或多个字节码偏移量,代表要跳转到的位置