不考虑继承时,对象初始化的过程在视频中都有,考虑继承时,java对象的初始化过程,也可以先用代码验证一下:
//验证一个有父类的java对象的初始化顺序
class InitFu{
public static String staticFuField = "父类静态变量";
public String field="父类成员变量";
public int f;
static{
System.out.println(staticFuField);
System.out.println("父类静态初始化块");
}// 静态初始化块
{
System.out.println("父类成员变量默认值:"+f);
System.out.println(field);
System.out.println("父类构造代码块");
}// 初始化块
InitFu(){
System.out.println("Fu类初始化");
}
}
public class InitStatic extends InitFu
{
public static String staticField = "子类静态变量";// 静态变量
public String field = "子类成员变量";// 变量
public int z;
static{
System.out.println(staticField);
System.out.println("子类静态初始化块1,位置在前");
}// 静态初始化块
{
System.out.println("子类成员变量还是默认值:"+z);
System.out.println(field);
System.out.println("子类构造代码块1,位置在前");
}// 初始化块
static{
System.out.println("子类静态初始化块2,位置在后");
}// 静态初始化块
public InitStatic() {
System.out.println("子类构造函数");
}// 构造函数
public static void main(String[] args) {
new InitStatic();
}
{
//System.out.println(field);
System.out.println("子类构造代码块2,位置在后");
}// 初始化块
}
运行结果是:
父类静态变量
父类静态初始化块
子类静态变量
子类静态初始化块1,位置在前
子类静态初始化块2,位置在后
父类成员变量默认值:0
父类成员变量
父类构造代码块
Fu类初始化
子类成员变量还是默认值:0
子类成员变量
子类构造代码块1,位置在前
子类构造代码块2,位置在后
子类构造函数
这样再分析楼主的代码就容易理解了:
- class Base{
- private int i = 2;//1.最先执行的
-
- Base(){ //2. 第2个顺序执行的,虽然Derved类的构造函数中把super()写在第一行,但不是说是执行到Derived()后才执行父类构造函数
- System.out.println("base:"+this.i); //打印:base:2,因为Base()方法执行是在父类中,所以这里的i是父类的,不是子类的。
- this.display(); //这里调用的是子类的display()方法,因为内存中只有一个子类对象,this就是指向子类对象,而且子类复写了display()方法,这是多态特征,调用的是的子类方法。
- }
- public void display(){
- System.out.println("base display:"+this.i);
- }
- }
- class Derived extends Base {
- public int i = 22;
- {
- System.out.println(i+"ooooo");
- }
- public Derived(){
- super(); //
- System.out.println(i+"ccccc");
- i = 222;
- }
- public void display(){ //3. 从上面的顺序2跳转到这里执行
- System.out.println("derived display:"+i); //因为display()这个函数是在父类构造函数中执行的,Base()还没执行完,子类自己的成员变量i还没有显示初始化,还是默认值
- }
- }
- class TestI {
- public static void main(String[] args){
- new Derived();
- }
- }
复制代码
欢迎指正~ |