层次初始化
层次初始化:类的初始化时分层进行的,在继承中,先进行父类对象的初始化过程,等父类对象的初始化过程结束后,再进行子类对象的初始化过程。
解释:在子类的构造方法中,无论是显式或隐式调用super(),都会先把父类的成员变量进行初始化过程(构造代码块 -> 构造方法),当父类的初始化过程结束后,然后在进行子类的初始化过程(构造代码块 -> 构造方法)。
理解:(先父后子)必须先有父类,后有子类。没有父类就不会有子类。
特殊:
static用来修饰类的变量或者方法,必须是随类的加载而加载,必须会早于对象的初始化过程。(父类的静态初始化 > 子类的静态初始化)
代码:
class Father { static { System.out.println("静态代码块 Father");//随类而加载(1次) } { System.out.println("构造代码块 Father");//随对象创建而执行(多次) } public Father() { System.out.println("构造方法 Father"); } } class Son extends Father { static { System.out.println("静态代码块 Son");//随类而加载(1次) } { System.out.println("构造代码块 Son");//随对象创建而执行(多次) } public Son() { System.out.println("构造方法 Son"); } }
打印结果:
静态代码块 Father 静态代码块 Son 构造代码块 Father 构造方法 Father 构造代码块 Son 构造方法 Son
结论:
(1)父子的初始化顺序:父类初始化 > 子类初始化。
(2)类的静态代码块:父类的静态代码块 > 子类的静态代码块。这步是随类的加载而加载。
(3)对象的初始化过程:父类对象的初始化过程(构造代码块 -> 构造方法)> 子类对象的初始化过程(构造代码块 -> 构造方法)。这步是随类的加载而加载。
(4)类的静态代码块 > 对象的初始化过程。
(5)类的加载 > 对象的创建。
最后:
父类的静态代码块 > 子类的静态代码块 > 父类对象的初始化过程(构造代码块 -> 构造方法)> 子类对象的初始化过程(构造代码块 -> 构造方法)。