闲话不多说,直接上代码
Base父类
package com.gjp.Init;
public class Base {
//静态变量
private static int a = 10;
//静态代码块
static {
System.out.println("Base静态代码块执行,a=" + a);
staticMethod();
}
//静态方法
private static void staticMethod() {
System.out.println("Base静态方法执行");
}
//构造代码块
{
System.out.println("Base构造代码块执行");
method();
}
//非静态变量
private int b = 100;
//构造方法
public Base() {
System.out.println("Base构造函数执行,b=" + b);
}
//非静态函数
private void method() {
System.out.println("Base非静态方法在构造代码块中执行执行");
}
}
package com.gjp.Init;
public class Child extends Base{
//静态变量
private static int a = 10;
//静态代码块
static {
System.out.println("Child静态代码块执行,a=" + a);
staticMethod();
}
//静态方法
private static void staticMethod() {
System.out.println("Child静态方法执行");
}
//构造代码块
{
System.out.println("Child构造代码块执行");
method();
}
//非静态变量
private int b = 100;
//构造方法
public Child() {
System.out.println("Child构造函数执行,b=" + b);
}
//非静态函数
private void method() {
System.out.println("Child非静态方法在构造代码块中执行");
}
}
Main函数
package com.gjp.Init;
public class Demo {
public static void main(String[] args) {
Child c = new Child();
}
}
输出结果如下:
Base静态代码块执行,a=10
Base静态方法执行
Child静态代码块执行,a=10
Child静态方法执行
Base构造代码块执行
Base非静态方法在构造代码块中执行执行
Base构造函数执行,b=100
Child构造代码块执行
Child非静态方法在构造代码块中执行
Child构造函数执行,b=100
从输出结果可以看出,类的初始化,首先会找到最顶层的父类,并先初始化静态变量和静态方法,为什么呢?可以从第一行输出的变量a和静态方法看出,如果没有先初始化静态变量和静态方法,那么在写代码的时候IDE就会报错,而且a的值也会是0
所以首先执行的顺序是:
父类静态变量->父类静态方法->父类静态代码块
好了,往下看,会看到Child字样,没错,父类和static相关的都初始化成功之后,就该子类了,顺序和父类没区别
顺序如下:
子类静态变量->子类静态方法->子类静态代码块
继续往下看,又看到Base字样,这时就是初始化父类的构造代码块了,然后看上面的代码可以看出,非静态函数可以在构造代码块中执行,而这时可能你会问,非静态变量呢? 是的我没有在构造代码块中输出b的值,是因为在构造代码块中调用非静态变量,IDE会提示:Cannot reference a field before it is defined这个错误,意思大概是不能引用未定义的字段也就是变量,继续往下,看到构造函数执行,此时的b成功打印出来,值也为100,可以推断出变量是紧接着构造代码块初始化的,否则在构造函数中是无法调用的,就算能调用,值也是0。
由此得出顺序:
(在这里我不知道非静态函数为什么能在构造代码块中执行,我猜想的应该是在构造代码块之前初始化,或者直接入堆不需要初始化,还请知道的人告知我一下,在此谢过~)
父类非静态函数->父类构造代码块->父类非静态成员变量->父类构造函数
好了往下看Child和父类的初始化顺序基本一致
顺序如下:
子类非静态函数->子类构造代码块->子类非静态成员变量->子类构造函数
上面已经分析的很详细了,得出最终类的初始化顺序结论:
父类静态变量->父类静态方法->父类静态代码块
子类静态变量->子类静态方法->子类静态代码块
父类非静态函数->父类构造代码块->父类非静态成员变量->父类构造函数
子类非静态函数->子类构造代码块->子类非静态成员变量->子类构造函数
这个是我自己分析的,如果有经验者,我哪里写错了,请给我留言,让我纠正