先看一下 下面的代码,小伙们先分析一下输出的内容是什么
public class StaticDemo {
public static void main(String[] args) {
new SB();
}
}
class SA{
SD d;
static {
System.out.println("A1");
}
{
System.out.println("A2");
d = new SD();
}
public SA(){
System.out.println("A3");
}
}
class SB extends SA{
static SC c = new SC();
static {
System.out.println("B1");
}
{
System.out.println("B2");
}
public SB(){
System.out.println("B3");
}
}
class SC{
public SC(){
System.out.println("C");
}
}
class SD extends SC{
public SD(){
System.out.println("D");
}
}
答案:A1 C B1 A2 C D A3 B2 B3
有的小伙们可以会有疑问 为什么呢? 下面我们就一起来分析一下。
我们要先知道 static 关键字的特性,static 所修饰内容在类加载中加载到方法区。(类加载优先于创建对象),构造代码块 和构造方法在创建对象时执行,并且构造代码块优先于构造方法执行。
1 我们从main方法进入 开始执行 new SB(),即创造一个Sb匿名对象
2 接下来来到SB类 发现 它继承与SA ,根据继承的特性可知 创建一个对象时先创建它的父类,即Sa,创建对象之前要加载类,加载类的过程中会先执行static关键字
3 SA类加载完成后,就要加载子类SB,加载SB的过程中也会执行static ,SB中有两个static 按照先后顺序,先执行第一个static ,即static SC c=new SC();我们就到了SC类,输出C,然后继续执行第二个static,输出B1
4类加载完成后就要创建对象,和类的加载一样,先创建父类的对象,即Sa,这时构造代码块会先执行,输出A2 接着创建SD类对象,SD为DC的子类,所以要先创建父类SC,输出C,然后创建SD,输出D,然后再执行SA中的构造方法,输出A3
5 SA对象创建完成后,创建SB对象,执行SB中的构造代码块,输出B2,在执行SB中的构造方法,输出B3
总结 执行顺序:父类静态--->子类静态---->父类非静态---->子类非静态