先抛出一个问题,下面代码的执行结果是什么呢?
public class ClassLoaderLinkTest {
public static void main(String[] args) {
// 5 Father加载static{}
// 2 Son加载static{}
Son son = new Son();
System.out.println("=========================END==========================");
}
}
// 子类SON
public class Son extends Father{
// 类先初始化 再加载 初始化的时候执行static修饰的方法 父类在子类之前初始化
private int i=0;
private long l=2L;
static int ssi=3;
{
System.out.println("1 SON 加载{}代码块");
}
// 类加载的时候执行初始化
static {
System.out.println("2 SON 加载static{}代码块");
}
public Son(){
l=3L;
System.out.println("3 SON 加载构造方法");
}
}
// 父类Father
public class Father {
int i1;
static int fsi=4;
static Son son=new Son(); // 此处执行SON的初始化
{
System.out.println("4 father 加载{}代码块");
}
static {
System.out.println("5 father 加载static{}代码块");
}
Father(){
i1=1;
System.out.println("6 father 加载构造方法");
}
}
执行结果你知道吗?你写出答案的原因是什么呢?
4 father 加载{}代码块
6 father 加载构造方法
1 SON 加载{}代码块
3 SON 加载构造方法
5 father 加载static{}代码块
2 SON 加载static{}代码块
4 father 加载{}代码块
6 father 加载构造方法
1 SON 加载{}代码块
3 SON 加载构造方法
=========================END==========================
规律
第一点,所有的类都会优先加载基类
第二点,静态成员的初始化优先
第三点,成员初始化后,才会执行构造方法
第四点,静态成员的初始化与静态块的执行,发生在类加载的时候。
第四点,类对象的创建以及静态块的访问,都会触发类的加载。
如果补充构造代码块
1. 执行父类的静态代码块,并初始化父类静态成员变量
2. 执行子类的静态代码块,并初始化子类静态成员变量
3. 执行父类的构造代码块,执行父类的构造函数,并初始化父类普通成员变量
4. 执行子类的构造代码块, 执行子类的构造函数,并初始化子类普通成员变量