/***
* java虚拟机规范
* 虚拟机结构
* @字节码指令集简介
* java虚拟机的指令由一个字节长度的,代表着某种特定操作含义的操作码以及跟随其后的零至多个代表此操作所需参数的操作数所构成。
* 虚拟机中许多指令并不包含操作数,只有一个操作码。
*
* @数据类型和java虚拟机
* java虚拟机中大多数指令都包含了其所操作的数据类型信息
*
* @加载和存储指令
* 用于将数据从栈帧的本地变量表和操作数栈之间来回传递
* 将一个本地变量加载到操作数栈的指令——————load*
* 将一个数值从操作数栈存储到局部变量表——————store*
* 将一个常量加载到操作数栈的指令————push*,dc*,dc2_w*,const*,
* 用于扩充局部变量表的访问索引或者立即数的指令————wide
* 访问对象的字段或数组元素的指令同样也会与操作数栈传递数据。
*
* @算数指令
* 整型和浮点型算数执行运算
* byte,short,char,boolean类型的运算通过int类型的指令运算
* @见图一
*
*/
图一来源《java虚拟机规范》
/**
* @类型转换指令
* 可以在两种java虚拟机数值类型之间相互转换
* java虚拟机支持宽化类型转换(小范围类型向大范围类型的安全转换)
* i2l,i2f,i2d等等 显而易见的源类型和目标类型,2表示 to
* 精度丢失是从整数转为浮点数发生,具体根据IEEE 754
*
* ¥窄化类型转化
* 上限溢出,下限溢出,精度丢失这些窄化转换不会导致虚拟机抛出运行时异常
* 但是可能导致IEEE 754中定义的浮点异常信号混淆
* @对象的创建和操作
* 类实例和数组都是对象,但java虚拟机提供了不同的字节码指令
* #创建类实例的指令 new
* #创建数组指令 newarray anewarray multianewarray
* #访问类字段(static字段,类变量)和实例字段(实例变量)的指令 getfield putfield getstatic putstatic
* #把一个数组元素加载到操作数栈的指令 baload caload saload iaload …… aaload
* #把一个操作数栈的值存储到数组元素中的指令
* 类型+astore
* #取数组长度 arraylength
* #检查类实例或数组类型的指令 instanceof checkcast
*
* @操作数栈管理指令
* java虚拟机提供了一些用于直接控制操作数栈的指令
* pop,pop2,dup,dup2,dup*,swap
* @控制转移指令
* 可以让java虚拟机有条件或无条件从指定指令而不是控制转移指令的下一条指令继续执行程序
* 条件分支 ifeq,ifne,iflt,ifle,ifgt,ifge,ifnull,ifnonnull,if_icmpeg,if_icmpne*
* 复合条件分支 tableswitch lookupswitch
* 无条件分支 goto goto*,jsr,jsr* ret
* java虚拟机中有专门的条件分支指令集用来处理int和reference类型的比较操作
* 而且也有专门的指令用来检测null值,所以无需用某个具体的值来表示null
*
* @方法调用和返回指令
* #invokevirtual
* 用于调用对象的实例方法,根据对象的实例类型进行分派(虚方法分派)。这也是JAVA语言中最常见的方法分派方式
*
* #invokeinterface
* 用于调用接口方法,在运行时搜索由特定对象所实现的这个接口方法,并找出合适方法进行调用
*
* #invokespecial
* 用于调用一些需要特殊处理的实例方法,包括实例初始化方法,私有方法,父类方法
*
* #invokestatic
* 用于调用命名类中的类方法(static)
*
* #invokedynamic
* 用于调用以绑定了invokedynamic指令的调用点对象作为目标的方法
* 调用点对象是一个特殊的语法结构,当一条invokedynamic指令首次被虚拟机执行前
* 虚拟机会执行一个引导方法(bootstrap method)并以这方法的运行结果作为调用点对象。
* 因此,每条invokedynamic指令都有独一无二的链接状态,这是它与其他方法调用的一个差异
*
* @抛出异常
* 程序中显式抛出异常的指令 athrow实现
* 其他检测到的异常由虚拟机自动抛出
*
* @同步
* java虚拟机可以支持方法级的同步和方法内部一段指令的同步
* 这两种同步结构都是使用同步锁(monitor)来支持的
*
* @方法级同步时隐式的,即无需通过字节码指令来控制,它实现在方法调用和返回操作中
* 虚拟机从方法常量池中的方法表结构中的ACC_SYNCHRONIZED访问标志区分一个方法是否同步
* 如果是持有同步标志,执行线程将先持有同步锁,然后执行方法,执行完毕后释放同步锁。
* @在方法执行期间,执行线程持有同步锁,其他任何线程都无法再获得同一个锁,
* 如果一个同步方法执行异常,并且方法在内部无法处理此异常
* 那么这个同步方法持有的锁将在异常抛出同步方法外时自动释放
*
* @指令级序列同步通常是java语言中的关键字——synchronized
* java虚拟机的指令集中有monitorenter,monitorexit 支持这个关键字的语义。
* 需要java虚拟机和编译器协作支持
*
*/