Java程序初始化顺序

1.按Java理论,父类与子类的初始化顺序为:

1.初始化父类静态变量

2.初始化父类的静态代码块

3.初始化子类的静态变量

4.初始化子类的静态代码块

5.父类的非静态变量

6.父类的非静态代码块

7.父类的构造函数

8.子类的非静态变量

9.子类的非静态代码块

10.子类的构造函数

验证代码:

public class Base {
    static
    {
        System.out.println("Base static block");
    }
    {
        System.out.println("Base block");
        //draw();
    }
    public  Base()
    {
        System.out.println("Base constructor");
    }
    public  void draw()
    {
        System.out.println("Base draw");
    }
}
public  class Deived extends Base{
    private  int radi=1;
    static {
        System.out.println("Deived static block");
    }
    {
        System.out.println("Deived block");
    }
    public  Deived(int x)
    {
        radi =x;
        System.out.println("Deived constructor");
        //draw();
    }
    public  static void  main(String args[])
    {
        new Deived(5);
    }
    @Override
    public  void draw()
    {
        System.out.println("Deived draw "+radi);
    }
}
结果如下:
Base static block
Deived static block
Base block
Base constructor
Deived block
Deived constructor

这个理论从大的方面看没问题,但有一个疑问:类的方法在什么时候初始化呢?

修改代码如下(取消draw方法注释):

public class Base {
    static
    {
        System.out.println("Base static block");
    }
    {
        System.out.println("Base block");
        draw();
    }
    public  Base()
    {
        System.out.println("Base constructor");
    }
    public  void draw()
    {
        System.out.println("Base draw");
    }
}
public  class Deived extends Base{
    private  int radi=1;
    static {
        System.out.println("Deived static block");
    }
    {
        System.out.println("Deived block");
    }
    public  Deived(int x)
    {
        radi =x;
        System.out.println("Deived constructor");
        draw();
    }
    public  static void  main(String args[])
    {
        new Deived(5);
    }
    @Override
    public  void draw()
    {
        System.out.println("Deived draw "+radi);
    }
}

结果如下:

Base static block
Deived static block
Base block
Deived draw 0
Base constructor
Deived block
Deived constructor
Deived draw 5

根据结果说明,在父类在初始化的时候就能调用子类的draw方法,将调用draw代码放在父类构造函数时结果也一样。说明类的方法初始化与此次字段的初始化顺序没有关系,在这些步骤之前就已经存在该方法了。

所以将经典理论补充完善如下:

父类(子类)方法初始化(先后顺序未知)->

父类静态字段-父类静态方法块->

子类静态字段->子类静态方法块->

父类非静态字段->父类非静态方法块->父类构造函数->

子类非静态字段->子类非静态方法块->子类构造函数。

如有错误,欢迎指出~

posted @ 2022-11-20 13:27  Shapley  阅读(373)  评论(0编辑  收藏  举报