Java高级——字节码指令

字节码指令

  • 字节码指令
  • 加载和存储指令
  • 运算指令
  • 类型转换指令
  • 对象创建和访问指令
  • 操作数栈管理指令
  • 控制转移指令
  • 方法调用和返回指令
  • 异常处理指令
  • 同步指令
  • 大全

字节码指令

JVM采用操作数栈架构,指令由操作码Opcode+操作数Operand构成

  • 大多指令不包含操作数,只有一个操作码,指令参数放在操作数栈
  • 操作码长度为一个字节,故总数不能超过256
  • 操作数未长度对齐,需在运行时重构回去
  • 操作码隐含数据类型,如iload从局部变量表中加载int数据到操作数栈中,a代表reference
  • byte和short符号扩展为int,boolean和char零位扩展为int

加载和存储指令

用于将数据在栈帧中的局部变量表和操作数栈之间的来回传输

  • 将一个局部变量加载到操作数栈: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

其中n代表数字,将操作数隐含到指令中

运算指令

用于对两个操作数栈上的值进行某种特定运算,并把结果重新存入到操作栈顶,可分为对整数和对浮点数进行运算的指令

  • 加: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

整型数据运算可能会导致溢出

除和求余中当除数为0时抛出ArithmeticException异常

类型转换指令

将两种不同的数值类型相互转换,一般用于显示转换

JVM直接支持宽化类型转换,无需显示的转换

  • int 转为 long、float、double
  • long 转为 float、double
  • float 转为 double

而窄化类型转换,必须显式使用转换指令

  • i2b、i2c、i2s、l2i、f2i、f2l、d2i、d2l、d2f

int或long窄化转换为其他整型时直接高位截断,可能导致符号位改变

浮点值窄化转换为其他整型时

  • 若为NaN,结果为0
  • 若是无穷大,则向零舍入取整,若取整后不在表示范围,则为最大或最小正数

doulbe转为float时

  • 向最接近数舍入
  • 若转换结果的绝对值太小,则返回float的正负0
  • 若转换结果的绝对值太大,则返回float类型的正负无穷大
  • NaN依旧为NaN

对象创建和访问指令

用于创建和访问对象和数组实例

  • 创建类: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

控制转移指令

让JVM有条件或无条件地从指定位置指令的下一条指令继续执行程序

  • 条件分支: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

long、float、double的条件分支操作,会先执行比较运算指令得到int值,再执行int类型的条件分支指令来完成分支跳转

方法调用和返回指令

方法调用

  • invokevirtual:调用对象实例方法,根据对象的实际类型进行分派(虚方法分派)
  • invokeinterface:调用接口方法,会在运行时搜索实现这个接口方法的对象,找出适合的方法进行调用
  • invokespecial:调用一些需要特殊处理的实例方法,包括构造方法、私有方法和父类方法
  • invokestatic:调用static方法
  • invokedynamic:在运行时动态解析出调用点限定符所引用的方法并执行,分派逻辑由用户所设定的引导方法决定

方法返回

  • ireturn、lreturn、freturn、dreturn、areturn,return(void)

异常处理指令

显式抛出异常的操作(throw语句)都由athrow指令来实现

运行时异常会在其他指令检测到异常时自动抛出

处理异常(catch语句)不由字节码指令实现,而是采用异常表

同步指令

JVM通过管程(Monitor)可以支持方法级的同步和方法内部一段指令序列的同步

方法级的同步无须通过字节码指令来控制,当方法调用时检查ACC_SYNCHRONIZED,如果设置了,线程就要先持有管程才能执行方法,方法完成时释放管程

同步一段指令序列由synchronized语句块表示,monitorenter和monitorexit实现

大全

Java高级——字节码指令_第1张图片
Java高级——字节码指令_第2张图片
Java高级——字节码指令_第3张图片
Java高级——字节码指令_第4张图片
Java高级——字节码指令_第5张图片
Java高级——字节码指令_第6张图片
Java高级——字节码指令_第7张图片

你可能感兴趣的:(#,Java高级,java,jvm,开发语言)