Java 继承关系中:static,构造函数,成员变量的加载顺序

首先看下面的例子:

package simple.demo;

/**
 * @author Administrator
 * @date 2019/01/03
 */
public class ClassA {
    ClassB classB1 = new ClassB();
    static {
        System.out.println("ClassA static=========");
        ClassB classB2 = new ClassB();
    }
    public ClassA(){
        System.out.println("ClassA 构造函数=========");
    }
}
package simple.demo;

/**
 * @author Administrator
 * @date 2019/01/03
 */
public class ClassB {
    static {
        System.out.println("ClassB static=========");
    }
    public ClassB(){
        System.out.println("ClassB 构造函数=========");
    }
}
package simple.demo;

/**
 * @author Administrator
 * @date 2019/01/03
 */
public class ClassC extends ClassA{
    ClassB classB3 = new ClassB();
    static {
        System.out.println("ClassC static=========");
    }
    public ClassC(){
        System.out.println("ClassC 构造函数=========");
    }

}
package simple.demo;

/**
 * @author Administrator
 * @date 2019/01/03
 */
public class Test {
    public static void main(String[] args){
        ClassC classC = new ClassC();
    }
}

如果没有看结果,你能猜想输出什么 吗?

输出结果为:

ClassA static=========
ClassB static=========
ClassB 构造函数=========
ClassC static=========
ClassB 构造函数=========
ClassA 构造函数=========
ClassB 构造函数=========
ClassC 构造函数=========

分析:

 1、执行main方法的  ClassC classC = new ClassC(); 要实例化ClassC必须先加载ClassC,因为ClassC继承于ClassA,所以加载ClassC之前先加载ClassA,所以加载ClassA的时候,就执行ClassA的static块的内容。

      先输出: System.out.println("ClassA static=========");

2、输出完1步的内容后,紧接着执行 ClassB classB2 = new ClassB(); 要实例化ClassB必须要先加载ClassB,所以ClassB的static块里面的内容要执行:System.out.println("ClassB static=========");

3、输出完2步的内容后,就要实例化ClassB了,所以执行ClassB的构造函数:System.out.println("ClassB 构造函数=========");

4、输出完3步的内容后,ClassA已经加载完毕,就应该加载ClassC了,所以输出:System.out.println("ClassC static=========");

5、输出完4步的内容后,ClassC已经加载完毕,就应该实例化ClassC了,要实例化ClassC就必须得先实例化ClassA, 因为子类的构造方法都会调用父类的构造方法。实例化ClassA之前必须先获取ClassA的所有属性,所以执行 ClassB classB1 = new ClassB();

6、 要执行ClassB classB1 = new ClassB(),必须先加载ClassB,因为ClassB已经在第2步的时候加载过,所以static快的内容不会再执行,只会执行ClassB的构造方法,输出:System.out.println("ClassB 构造函数=========");

7、输出完6步的内容后,已经获取了ClassA的所有属性,开始执行ClassA的构造函数了,输出:System.out.println("ClassA 构造函数=========");

8、输出完7步的内容后,ClassA已经实例化完毕,紧接着实例化ClassC,实例化ClassC之前要获取ClassC的所有属性,所要要执行:ClassB classB3 = new ClassB();

9、 要执行ClassB classB3 = new ClassB(),必须先加载ClassB,因为ClassB已经在第2步的时候加载过,所以static快的内容不会再执行,只会执行ClassB的构造方法,输出:System.out.println("ClassB 构造函数=========");

10、最后执行ClassC的构造函数,所以输出:System.out.println("ClassC 构造函数=========");

原文地址:https://www.cnblogs.com/boshen-hzb/p/6245261.html