首先第一个问题:
子类在创建实例后,类初始化方法会调用父类的初始化方法(除了java.lang.Object类,因为java.lang.Object类没有父类),而这种调用会逐级追述,直到java.lang.Object的初始化方法。这个地方所说的是初始化方法,而不是构造方法,因为构造方法是相对于java源程序而言,而编译后的class文件是初始化方法即" <init>"方法,初始化方法是由java源程序的三个部分组成的,一个部分是成员字段后的直接的初始化语句,例如private int i=0;private Date date=new Date();等等,第二个部分是由初始化块组成,例如:
public class Test{
private int i=0;//初始化第一部分
//以下大括号内为初始化第二部分
{
this.i=4; //do something......
}
}
第三个部分就是java源代码中的构造方法中的代码,java源代码中有几个构造方法,那么class文件中就有几个初始化方法,编译器会把第一部分与第二部分分别复制到每个初始化方法的前端,然后把初始化方法对应参数的构造方法的代码复制到相应初始化方法中(这里说的复制其实应该说是编译,不过为了让你更好理解所以如此说).那么说初始化方法如何追述其父类的,这也关系到初始化方法的结构,初始化方法的执行顺序以及结构就如上所说,但是每个初始化方法的第一个执行指令就是调用另外一个初始化方法,这个初始化方法可能是自身类某个初始化方法,例如你的构造函数中第一句有类似this(...)这种语句,那么初始化方法就会调用自身类的指定构造方法;如果你的构造方法中没有指定构造方法调用,那么初始化方法会默认调用父类无参数初始化方法,如果你的子类第一句为 super(....),那么初始化方法会调用父类指定初始化方法。这种调用过程会递归进行调用,直到这个类是java.lang.Object类。调用初始化方法并不代表会生成对象,你的java代码中出现new关键字加上构造方法的调用,只会生成一个对象,其父类对象不会生成。而且初始化方法对于虚拟机来说只是一个名称叫做" <init>"的普通方法,区别只是生成对象以后调用而已。
ps. 调用创建对象未必需要调用构造方法,比如反序列化。
第二个问题:参考 http://hxraid.iteye.com/blog/687660