(1)字节码指令-cinit
构造方法可以分为两类,一类是cinit 一类init
cinit是整个类的构造方法
putstatic:进行static变量的赋值,是到常量池里找到名字一个叫做i的变量
(2)字节码指令-init
init是:每个构造对象的构造方法
对成员变量的赋值,初始化代码块,构造方法里面的代码,最终呢也也会收集成同一个方法,会把这些代码最终呢合并在一起
以上呢就是对整个构造方法,关联到成员变量赋值操作,初始化代码块以后的执行的流程
(3)方法的调用
我们来看看不同的方法他们调用的字节码指令是否一样
如果是构造方法调用的是invokespecial 私有也是调用 invokespecial final也是调用的invokespecial 普通的public调用的invokevirtual 两次静态方法调用的invokestatic
public的方法是不能唯一确定的,它可能出现方法重写的情况,因此在编译期间他不能唯一确定它调用的是那个方法,也许是子类的也许是父类的invokevirtual 所以称之为动态绑定,需要在运行的时候确定
在性能上invokespecial 和invokestatic性能更高一些因为他属于静态绑定,将来就能找到方法的执行地址了,invokevirtual需要确定多次才能确定方法的执行地址这是这几个方法调用的指令
pop是静态方法的调用是不需要对象的pop把对象出栈
(4)多态原理-HSDB
invokevirtual是显现方法的多态调用,它的工作方式相对较为复杂,下面研究一下执行流程
使用虚拟机工具可以看到我们虚拟机中比较底层的内存状态和内存地址
(5)多态原理-查找类
查询Dog这个对象:查询出对象在内存中的地址
这个对象呢分了对象头,成员变量,这里质包含了对象头16个字节:前8个字节mark1:包含对象的哈希吗以及后来加锁时的锁标记,后面8个字节是对象的类型指针,根据对象的类型指针可以找到Class类
可以查看这俩内存的实际地址:
对象类型 指针的类型表示:Dog在java虚拟机里的样子,它是处在方法区包含了这个类的所有信息
常量池的指针地址,方法入口的指针地址
(6)多态原理-vtable
下面我们来看类中的方法指那种多态的方法它是存在一种交vtable的虚方法表中,前面提到的静态方法,final方法,私有方法,他们不会列在这个虚方法表中,他在类的结构的