字节码指令
Java虚拟机的指令由一个字节长度的,代表某种特定操作含义的数字,称之为操作码,以及跟随其后的零至多个代表此操作所需参数的操作数而构成。
操作码的长度为1个字节,因此最大只有256个。
基于栈的指令集架构
加载和存储指令
加载和存储指令用于将数据在栈帧中的局部变量表和操作数栈之间来回传输。
将一个局部变量加载到操作栈:iload、iload_、lload、lload_、fload、fload_、dload、dload_、aload、aload_。
将一个数值从操作数栈存储到局部变量表:istore、istore_、lstore、lstore_、fstore、fstore_、dstore、dstore_、astore、astore_。
将一个变量加载到操作数栈:bipush、sipush、ldc、ldc_w、ldc2_w、aconst_null、iconst_m1、iconst_、lconst_、fconst_、dconst_。
扩充局部变量表的访问索引的指令:wide
_都是某个带有一个操作数的通用指令的特殊形式,它们省略了显示的操作数,不需要进行取操作数的动作,因为实际上操作数就隐含在指令中。
运算指令
用于对两个操作数栈上的值进行某种特定运算,并把结构重新存入到操作栈顶。
加法指令:iadd、ladd、fadd、dadd
减法指令:isub、lsub、fsub、dsub
乘法指令:imul、lmul、fmul、dmul
除法指令:idiv、ldiv、fdiv、ddiv
求余指令:irem、lrem、frem、drem
取反指令:ineg、lneg、fneg、dneg
位移指令:ishl、ishr、iushr、lshl、lshr、lushr
按位或指令:ior、lor
按位与指令:iand、land
按位异或指令:ixor、lxor
局部变量自增指令:iinc
比较指令:dcmpg、dcmpl、fcmpg、fcmpl、lcmp
类型转换指令
类型转换指令可以将两种不同的数值类型相互转换。
宽化类型转换:
int类型到long、float或者doule类型
long类型到float、double
float类型到double
窄化类型转换:i2b、i2c、i2s、l2i、f2i、f2l、d2i、d2l、d2f。
对象创建与访问指令
创建类实例指令:new
创建数组指令:newarray、anewarray、multianewarray
访问类字段(类变量)和实例字段(实例变量)指令:getfield、putfield、getstatic、putstatic
把一个数组元素加载到操作数栈指令:baload、caload、saload、iaload、laload、faload、daload、aaload
将一个操作数栈的值储存到数组元素中指令:bastore、castore、sastore、iastore、fastore、dastore、aastore
取数组长度的指令:arraylength
检查类实例类型指令:instanceof、checkcast
操作数栈管理指令
将操作数栈的栈顶一个或两个元素出栈:pop、pop2
复制栈顶一个或两个数值并将复制值或双份的复制值重新压入栈顶:dup、dup2、dup_x1、dup2_x1、dup_x2、dup2_x2
将栈最顶端的两个数值互换:swap
控制转义指令
条件分支:ifeq、iflt、ifle、ifne、ifgt、ifge、ifnull、ifnonnull、if_icmpeq、if_icmpne、if_icmplt、if_icmpgt、if_icmple、if_icmpge、if_acmpeq、if_acmpne
复合条件分支:tableswitch、lookupswitch
无条件分支:goto、goto_w、jsr、jsr_w、ret
方法调用和返回指令
invokevirtual指令:用于调用对象的实例方法,根据对象的实际类型进行分派。
invokeinterface指令:用于调用接口方法,它会在运行时搜索一个实现了这个接口方法的对象,找出适合的方法进行调用。
invokespecial指令:用于调用一些需要特殊处理的实例方法,包括实例初始化方法、私有方法和分类方法
invokestatic指令:用于调用类静态方法
invokedynamic指令:用于在运行时动态解析出调用点限定符所引用的方法。
异常处理指令
athrow
同步指令
方法级的同步:隐式的,无须通过字节码指令控制,它实现在方法调用和返回操作之中。(方法访问标识ACC_SYNCHRONIZED)
代码块的同步:
monitorenter
monitorexit
领取专属 10元无门槛券
私享最新 技术干货