使用类实例
/**
* java虚拟机规范——虚拟机编译器
* @使用类实例
* java虚拟机类实例通过虚拟机指令new来创建。
* 在java虚拟机层面,构造函数会以一个编译器提供的名为<init>的方法出现——这个名字特殊的方法也成为实例化方法
* 一个类可以有多个构造函数,对应也有多个实例化初始化方法。
* 在把类实例新建好,并将其实例变量——包括父类——都初始化为各自的默认值之后,接下里就需要调用这个类实例的实例化初始化方法。
*
* @图一 编译器的<init>初始化方法
*
*/
数组
@数组
java虚拟机中数组也是对象来表示,数组由专门的指令集创建和操作。
newarray 创建元素为数值类型的数组
anewarray 创建元素为引用类型的数组
multianewarray 创建多维数组使用
编译switch语句
@编译switch语句
编译器使用tableswitch和lookupswitch指令来生成switch语句的编译代码。
switch条件值int以下的自动转为int进行运算!比如byte 条件值 会在编译器转为int ,数值窄化为int
@tableswitch 只用用于标识switch结构中的case语句块,他可以高效的从索引表中确定case语句块的偏移量。
当switch语句中的条件值不能对应索引表中的任何一个case语句块的分支偏移量,default分支作用
@loopupswitch
当switch语句中case分支条件值比较稀疏可以使用lookupswitch
lookupswitch指令的索引表项由int类型的键(来源于case语句块后面的数值)与对应的目标语句偏移量所构成。
当lookupswitch指令执行时,switch语句的条件值将和索引表中的键进行比较。
如果条件符合,转移到这个键对应的分支继续执行,否则将执行default
java虚拟机规定: lookupswitch指令的索引表必须根据键值排序,这样使用将会比直接线性扫描更有效率。
使用操作数栈
@使用操作数栈
java虚拟机为方便使用操作数栈,提供了大量不区分操作数类型的指令。
java虚拟机不允许作用于操作数栈的指令去修改或者拆分那些不可拆分的操作数。
抛出异常和处理异常
@抛出异常和处理异常
@程序中使用throw关键字抛出异常,字节码使用athrow指令完成。
@每个catch语句都会使编译器在异常表中增加一个成员(一个异常处理器)
编译finally 语句块
@编译finally 语句块
@try-finally 把控制权转移到try结构外围之前,首先执行finally里的内容
无论try中是正常还是异常执行都是如此。
四种方法让程序退出try语句
1.语句块内的所有语句正常执行结束。
2.通过return语句退出方法
3.执行break或者continue语句
4.抛出异常
@finally在抛出异常之前执行完毕。
同步
@同步
java虚拟机中的同步使用monitor的进入和退出来实现的。
@无论显式(有明确的monitorenter和monitorexit)还是隐式同步(依赖方法调用和返回指令,方法中的标志位为同步方法实现)。
@同步方法是由方法调用指令运行读取运行常量池中的方法ACC_SYNCHRONIZED标识实现
@synchronized通常用于实现代码块同步
通过monitorenter和monitorexit字节码指令实现
注解
@注解
添加注解并且能够在运行时访问,编译器要生成一份具备以下特征的class文件
|这个class文件是用来标识接口的,ACC_INTERFACE,ACC_ABSTRACT标志会开启
|根据class文件的版本号决定是否开启 ACC_SYNTHETIC
|该接口的访问权限是包级别
|该接口的名称遵循package-name.package-info内部表示
|没有父接口
|该接口包含的成员均是由java语言规范所定义的成员
图片来源《java虚拟机规范》