从一个例子中解析JAVA新建一个对象的过程
先上代码,代码如下:
//父类
class Father {
/*8、执行初始*/
private int i = 9;
protected int j;
/*7、调用构造方法,创建默认属性和方法,完成后发现自己没有父类*/
public Father() {
/*9、执行构造方法剩下的内容,结束后回到子类构造函数中*/
System.out.println("i = " + i + ", j = " + j);
j = 39;
}
/*2、初始化根基类的静态对象和静态方法*/
private static int x1 = print("static Father.x1 initialized");
static int print(String s) {
System.out.println(s);
return 47;
}
}
//子类
public class Son extends Father {
/*10、初始化默认的属性和方法*/
private int k = print("Son.k initialized");
/*6、开始创建对象,即分配存储空间->创建默认的属性和方法。
* 遇到隐式或者显式写出的super()跳转到父类Father的构造函数。
* super()要写在构造函数第一行 */
public Son() {
/*11、初始化结束执行剩下的语句*/
System.out.println("k = " + k);
System.out.println("j = " + j);
}
/*3、初始化子类的静态对象静态方法,当然mian函数也是静态方法*/
private static int x2 = print("static Son.x2 initialized");
/*1、要执行静态main,首先要加载Son.class文件,加载过程中发现有父类Father,
*所以也要加载Father.class文件,直至找到根基类*/
public static void main(String[] args) {
/*4、前面步骤完成后执行main方法,输出语句*/
System.out.println("Son constructor");
/*5、遇到new Son(),调用Son对象的构造函数*/
Son son = new Son();
/*12、运行main函数余下的部分程序*/
System.out.println("Main Left");
}
}
从上面的代码的实现逻辑上我们可以看出,这段代码很简单就是想实例化一个Son对象,虽然代码很简单,但是在Java的虚拟机中却是一个非常复杂的过程,下面就对这个代码进行一下分析。
首先,Java虚拟机找到程序的入口,即(public static void main)这个主方法,作为程序的起点,然后JVM首先要进行类验证,检查Son这个类是否在内存已经加载,因为JVM采用的惰性加载机制,而且Son类在当前JVM中是第一次使用,所以JVM会找到该Son类的Class文件进行类的加载并进行初始化,即JVM经过加载、验证、准备、解析、初始化的过程来对Son类进行初始化。在对Son在加载的过程中,发现Son类继承了Father类,所以需要先对Father类进行类的加载以及初始化,然后再对Son类进行类的加载以及初始化。反映到代码的执行过程为:1,先执行Father类中的静态变量、静态代码块并对静态方法进行初始化定义;2,在执行Son类中的静态变量、静态代码并对静态方法进行初始化定义;3,完成对Son和其父类的Father类的加载和初始化。
然后,在JVM完成类的加载和初始化后,继续按照顺序执行main方法其他语句,当实行到Son son = new Son()这个语句中,JVM开始在堆中为son对象分配对象空间,然后调用Son的构造方法,进行对象的创建。在对Son的构建方法时,因为Son有父类,所以会先调用supper方法,先对Father父类进行对象的创建,其创建的过程为:1,找到父类的构造方法,先对父类的成员变量和成员方法进行实例化,使成员变量具有初始值,成员方法完成定义;2,执行构造方法中定义的代码,完成父类对象的构造;3,对子类的成员变量和成员方法进行实例化,使成员变量具有初始值,成员方法完成定义;4,执行构造方法中定义的代码,完成子类对象的构造。最终完成son对象的实例化。
总结,在new一个对象的过程中,java虚拟机首先会检查该类是否加载,如果没加载,会对其类和一系列父类,按照从父类到子类的顺序依次对类进行加载,使类的静态变量进行初始化,使类的静态方法进行定义;然后才开始进行对象的实例化,在实例化的过程中,也遵循先对父类进行实例化然后对子类进行实例化,在对父类和子类实例化中,依次按照先对成员变量和成员方法进行初始化和定义,然后对构造方法中的代码进行执行;最终完成对象的实例化。