Java 对象初始化顺序 执行顺序

先看一道Java面试题:

求这段程序的输出。

 

解答此题关键在于理解和掌握类的加载过程以及子类继承父类后,重写方法的调用问题:

 

从程序的执行顺序去解答:

1.编译;当这个类被编译通知后,会在相应的目录下生成两个.class 文件。一个是 Base.class,另外一个就是Base$Sub.class。这个时候类加载器将这两个.class  文件加载到内存

 

2、Base base= new Sub():

 

  声明父类变量base对子类的引用,JAVA类加载器将Base,Sub类加载到JVM(Java虚拟机);

 

3、JVM为Base,Sub 的的成员开辟内存空间

 

  此时,Base 和Sub类中的值为null;

 

4、new Sub();

 

  这个时候会调用Sub类的隐式构造方法,

     Sub的构造方法本质为:

     public Sub(){

  super();//  调用父类的构造方法必须在构造方法中的第一行,为什么呢?这是因为在一些程序的升级中,要兼容旧版本的一些功能,父类即原先的一些初始化信息也要保证  //被执行到,然后执行当前

  baseName = "sub";//子类字段初始化

      }

    new Sub()执行到super()这行代码也就是跑到父类中去执行了,我们跳转到父类中的无参构造方法中执行,最后执行Sub()中的baseName = "sub";

 

5、public Base() ;

      父类无参构造方法的本质为:

 

  public Base(){

 

  baseName= "base";//父类字段初始化

 

  callName();

 

    }

 

  即将父类的baseName赋值为“base”,赋值后调用callName();

 

6、callName()方法在子类中被重写,因此调用子类的callName(),子类的callName方法执行,打印输出的是子类的baseName 字段的值,而这个时候子类的构造函数中字段的赋值还未执行。

 

7、父类的构造函数执行完毕,这个时候又回到子类当中,从super()的下一行继续执行,这个时候才为子类字段baseName 分配好存储空间,随后为其赋值:

 

 可见,在baseName = "sub"执行前,子类的callName()已经执行,所以子类的baseName为默认值状态null;

 

二、总结

java对象初始化顺序
1.父类静态初始化方法 static{ }
2.子类静态初始化方法 static{ }
3.父类字段初始化 ,如private String name ="base"
4.父类非静态初始化方法 {}
5.父类构造方法
6.子类字段初始化,如private String name="sub";
7.子类非静态初始化方法{}
8 子类构造方法

你可能感兴趣的:(java,Java面试题)