转自:http://www.blogjava.net/cheneyfree/archive/2008/05/24/202643.html
类Person和子类Son,体现对象初始化流程的代码:
public class Person {
Bow b1 = new Bow(1);
static {
System.out.println("Person staticstatic块1");
}
{
System.out.println("Person hello非static块1");
}
Bow b2 = new Bow(2);
static Bow b3 = new Bow(3);
Person() {
System.out.println("PersonPerson类的构造器");
}
{
System.out.println("Person hello非static块2");
}
static {
System.out.println("Person staticstatic块2");
}
}
class Son extends Person {
Bow b4 = new Bow(4);
static {
System.out.println("Test staticstatic块1");
}
{
System.out.println("Test hello1非static块1");
}
Bow b5 = new Bow(5);
static Bow b6 = new Bow(6);
Son() {
System.out.println("TestTest类的构造器");
}
{
System.out.println("Test hello2非static块2");
}
static {
System.out.println("Test static2static块2");
}
public static void main(String[] args) {
System.out.println("main");
new Son();
}
}
class Bow {
Bow(int m) {
System.out.println("Bow(" + m + ")");
}
}
执行结果:
Person static...static块1
Bow(3)
Person static...static块2
Test static...static块1
Bow(6)
Test static2...static块2
main...
Bow(1)
Person hello...非static块1
Bow(2)
Person hello...非static块2
Person...Person类的构造器
Bow(4)
Test hello1...非static块1
Bow(5)
Test hello2...非static块2
Test...Test类的构造器
从上面结果,可以总结出JAVA对象初始化的流程:
【1】父类static块和父类static属性(两者的执行先后顺序依据它们在类中具体位置由上至下)
【2】子类static块和子类static属性(两者的执行先后顺序依据它们在类中具体位置由上至下)
【3】执行main方法中new关键字之前的代码块
【4】父类非static块执行和父类非static属性(两者的执行先后顺序依据它们在类中具体位置由上至下,如果属性为实例类型,则执行该实例所在类的非static块和非static属性,再执行该类的构造器,即[4][5]步骤)
【5】父类构造器(完成非static属性初始值的设置)
【6】子类非static块执行和子类非static属性(两者的执行先后顺序依据它们在类中具体位置由上至下,如果属性为实例类型,则执行该实例所在类的非static块和非static属性,再执行该类的构造器,即[6][7]步骤)
【7】子类构造器(完成非static属性初始值设置,如果在子类构造器执行前就返回该非static属性,则该非static属值为属性默认值)
注:针对第【7】点“子类构造器执行前就返回该非static属性”,具体可以见下例:
public class ParentObjectInit {
public void test() {
}
public ParentObjectInit() {
test();
}
}
class ChildObjectInit extends ParentObjectInit {
private int instanceValue = 20;
public void test() {
System.out.println("instance1 value : " + instanceValue);
}
public static void main(String[] args) {
new ChildObjectInit();
}
}
这段代码的执行结果:
instance1 value is: 0 因为new 子类ChildObjectInit时,会先初始化父类ParentObjectInit,继而调用父来构造器器,接着执行此构造器中的test()方法,基于多态性,会转而调用子类的test()方法执行子类test()方法代码体,打印出instanceValue的属性默认值。(因为此时打印instanceValue值后,父类构造器才执行结束返回,根本还没轮到子类的初始化工作和子类构造器的执行。)