Java类加载和实例化的执行顺序详解

类加载:当程序主动使用某个类时,如果该类还未被加载到内存中,系统会通过加载,链接,初始化三个步骤来对类进行初始化,JVM连续完成三个步骤,统称为类加载或类初始化。
加载类的时机:第一次需要使用类信息时加载。
类加载的原则:延迟加载,能不加载就不加载。
触发类加载的几种情况:
(1)调用静态成员时,会加载静态成员真正所在的类及其父类。通过子类调用父类的静态成员时,只会加载父类而不会加载子类
(2)第一次 new 对象的时候加载,以后不需再次加载
(3)加载子类会先加载父类。

加载方法并不等于执行方法,初始化变量则会赋值。
类加载的顺序应为:加载静态方法—>初始化静态变量—>执行静态代码块
实例化时,先加载非静态方法—>实例化非静态变量—>执行构造代码块—>执行构造函数

public class InitializeDemo {
     
    //第一个加载的
    private static int k = 1;
    //第二个加载的
    /**
     * new 了一个实例,所以开始实例化
     * 1.加载非静态方法:{   print("构造块");  j=100; }
     * 2.实例化非静态方法: private int j = print("j");
     * 3.执行构造代码块::构造块 i= n=
     * 4.执行构造函数:private static InitializeDemo t1= new InitializeDemo("t1");
     */
    private static InitializeDemo t1= new InitializeDemo("t1");
    //第三个加载,具体实现同上
    private static InitializeDemo t2= new InitializeDemo("t2");
    //第四个加载 打印:i i= 6  n = 6
    private static int i = print("i");
    //第五个加载 加载静态代码块
    static {
     
        print("静态块");
        n = 100;
    }
    //第六个加载
    private static int n = 99;
    //第七个加载
    {
     
        print("构造块");
        j=100;
    }
    public InitializeDemo(String str) {
     
        System.out.println((k++) + ":" + str + " i= " + i + "  n = " + n);
        ++i;
        ++n;
    }
    //第八个加载:此变量在类加载的时候并不初始化,在实例化类的时候初始化(构造块,实例化的时候执行)
    private int j = print("j");
    public static int print(String str) {
     
        System.out.println((k++) + ":" + str + " i= " + i + "  n = " + n);
        ++n;
        return ++i;
    }
        public static void main(String[] args) {
     
            InitializeDemo n = new InitializeDemo("初始化");
        }
    }

结果如下所示:

1:构造块 i= 0  n = 0
2:j i= 1  n = 1
3:t1 i= 2  n = 2
4:构造块 i= 3  n = 3
5:j i= 4  n = 4
6:t2 i= 5  n = 5
7:i i= 6  n = 6
8:静态块 i= 7  n = 7
9:构造块 i= 8  n = 99
10:j i= 9  n = 100
11:初始化 i= 10  n = 101

你可能感兴趣的:(面试汇总,java)