java是面向对象的语言,与对象息息相关, 无时无刻都在创建对象,
对于创建对象,最熟悉的就是new 一个对象出来。
Object obj = new Object();
那么这个new 的过程在虚拟机之中又是怎么实现的呢?
通过阅读《JVM虚拟机》2.3.1对象的创建,简单总结了一下对象创建的过程。
个人见解:
1.虚拟机接收new指令
2.虚拟机接收new指令,检查类加载情况:
当虚拟机遇到一个new指令的时候,首先会去检查该指令中的参数,看是否能在常量池中定位到一个类的符号引用。
ps:常量池:用于存储编译期所生成 字面量 和 符号引用量 。 (一般会在.class文件中)
字面量:代码中定义的常量和变量。(常量池讲解例子)
符号引用量:在编译期,当对其他类的方法或类调用时,会以符号引用的形式(例如:Method java/lang/Object."<init>":()V object的init方法)
记录在.class文件中。
3-1.假如虚拟机检测到new指令中的参数可以定位到常量池中一个类的符号引用会继续检查该类是否已被加载,解析和初始化,若没有,则会先进行该类的加载过程。
3-2.如果没有定位到一个符号引用,继续执行下一步。
4.类加载检查过后,虚拟机将为对象分配内存。
分配内存有两种方案:指针碰撞 和 空闲列表
方案的选取取决于 内存是否规整决定的, 而内存是否规整则取决于 所选取的垃圾收集器是否有压缩整理的功能决定的。)
5.内存分配完后,虚拟机需要将分配到的内存空间初始化为零值(不包括对象头,ps:java堆的对象实例由 对象头,实例数据和对齐填充3部分组成),
初始化零值是保证了对象的实例字段在java代码中不赋初始值就可以直接使用,程序能访问到这些字段的数据类型所对应的零值。
public Class Eg{ private String eg1; private int eg2; /* *getset方法 */ }
即,可以直接使用 EG.getEg2() 方法返回0.
6.虚拟机为对象初始化零值后,就对对象进行一些必要的设置,例如哈希码,类信息等等
7.到此虚拟机的工作基本就完成,最后再由java程序执行<init>方法。