类的加载顺序

在牛客上看到一题,学习了一下,感觉非常有帮助,还是自己太菜了,
今后要多多学习牛客上的题目。

//问题:这个类在加载过程中的输出结果是什么?
public class Test {
    //t1是静态成员变量
    public static Test t1 = new Test();
    //构造代码块
    {
        System.out.println("blockA");
    }
    //静态代码块,静态块
    static {
        System.out.println("blockB");
    }

    public static void main(String[] args) {
        Test t2 = new Test();
    }
}
//运行main方法,输出结果是blockA blockB blockA

该类的加载过程是:

  • 因为static修饰的变量或者代码块(静态代码块),属于同一级别,所以谁在前就执行谁
    所以此时执行第一句:public static Test t1 = new Test();,加载静态对象t1
    此时等式右边是new Test(),创建实例对象,就会执行构造代码块中的内容,输出blockA
    然后会执行Test对象的构造函数,执行了默认的无参构造函数,本例没有显示写出。
  • 然后执行静态代码块,输出blockB,静态代码块只会执行一次
  • 最后执行Test t2 = new Test();,创建新的对象便会再一次执行构造代码块,构造函数,
    每创建一个对象时,就会执行构造代码块,构造函数,所以再次输出blockA

类的加载顺序

  1. 父类静态对象和静态代码块
  2. 子类静态对象和静态代码块
  3. 父类非静态对象(实例变量)和非静态代码块(构造代码块)
  4. 父类构造函数
  5. 子类非静态对象和非静态代码块
  6. 子类构造函数

其中:类中静态块按照声明顺序执行,谁在前先执行谁,
并且1和2步骤不需要调用new类实例的时候就执行了(意思是就是在类加载到方法区的时候执行的)

不会初始化子类的几种

  • 调用的是父类的static方法或者字段
  • 调用的是父类的final方法或者字段
  • 通过数组来引用