今天碰到这个问题,看了课程以及资料,做出解答。这是我自己绘制的图,按从上到下,从左到右的顺序执行。如有问题请联系我修正。
要点:
1、执行顺序分为两步,类加载和初始化阶段。
2、因为静态变量和静态代码块是属于类的,所以在类加载的时候就会执行,且只会执行一次。
3、无论是静态变量还是静态代码块,多个还是一个,它都会按照书写顺序去执行。【后面有代码测试】
4、普通代码块和构造函数是属于实例对象的,所以每次初始化一次就会执行一次。
5、注意:如果有父类,每初始化一次就会先执行父类的普通代码块和构造器。
6、执行的构造器是无参还是有参呢:因为java会自动给类装配一个无参构造器,所以在没有特殊定义的情况下会调用无参构造器。如自己去定义了一个有参构造器并且初始化的时候构造函数调用的是有参的,那它就会去执行有参的。【后面有代码测试】
代码测试:
父类:
public class Father {
public static String var = "静态变量father";
static {
System.out.println("静态代码块father, var==>" + var);
}
{
System.out.println("普通代码块father");
}
public Father() {
System.out.println("构造方法father");
}
public static void main(String[] args) {
System.out.println("执行father.main方法");
new Father();
}
}
子类:
public class Son extends Father{
public static String var = "静态变量son";
static {
System.out.println("静态代码块son, var==>" + var);
}
public Son() {
System.out.println("构造方法son");
}
public Son(String value) {
System.out.println("有参构造方法son, value==>" + value);
}
{
System.out.println("普通代码块son");
}
public static void main(String[] args) {
System.out.println("执行son.main方法");
new Son();
}
}
这里我们初始了一次子类,我们看下执行顺序,应该是先会执行父类的静态变量及静态代码块,然后再调用父类的普通代码块和构造器,最后执行子类的普通代码块和构造器:
结果正是这样。现在我初始化两次子类,看看是什么结果,使用分隔符划分一下,好观察一点。第二次初始化的时候就不会执行静态的东西了,因为静态的变量及代码块是属于类的,在第一次初始化的时候就已经进行类加载了。
结果截图:
关于第3点,静态变量和静态代码块的执行顺序 ,并且如果有多个的话会如何执行。我这里吧静态代码块和静态变量的书写顺序换一下,我在静态代码块里调用了静态变量,发现编译报错,这里就能说明静态变量和静态代码块的执行顺序是按照书写的顺序执行的。
我们也可以多写两个静态代码块来测试一下执行顺序:
执行顺序结果:
可以看到结果 是和我书写的顺序一致的。
再来看看第6点,执行的构造器是有参还是无参呢?这个就和我们调用的时候使用哪个构造器有关了,这里我写了一个无参,写了一个有参,我们分别在初始化的时候调用。
结果:
本篇文章到此结束。还有不同意见的可打在评论区一同探讨,一起共同进步。