对象初始化流程梳理

对象初始化流程梳理


类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值后,父类构造器才执行结束返回,根本还没轮到子类的初始化工作和子类构造器的执行。)

你可能感兴趣的:(对象初始化流程梳理)