结论:

1. 类的主动使用会导致类的初始化

   主动使用有: new 一个类的实例, 调用类的反射,访问类的静态变量或将静态变量庙会,调用类的静态方法,初始化一个类的子类,启动类main 方法所有类, JDK 1.7以后动态语言的调用

2. 创建对象时,先执行静态代码块,然后执行代码块,最后执行其构造方法

3.类的静态代码只有在类的初始化被执行(对应类对象在jvm只有一个),只能执行一次,  而类的代码块与构造方法直接与类的实例绑定在一起,创建几个实例,就会执行几次

4. 类的连接过程中的准备阶段 先于 类的初始化

5. 类先将类变量在准备阶段赋默认值 ,然后在初始化阶段设置成初始值

6. 子类被初始化时,先会初始化其父类

7. 调用类变量时,只会对类变量所在类进行初始化

8. 关于常量的初始化:

    8.1 常量在编译的过程中,会将其字面值存入到使用常量类中的静态池中,在使用常量的过程中是不会对常量所有类进行类的加载和初始化工作。

    8.2 如果常量是非字面量(引用类型,在编译期不能确认其值),那么访问该常量时,会导致常量所有类的初始化。

/**
 *
 *
 * 验证类的初始化:
 * 1. 子类被初始化时,先会初始化其父类
 * 2. 调用类变量时,只会对类变量所在类进行初始化
 *
 */
public class Test1 {

    public static void main(String[] args) {
//        System.out.println(Child1.a);
//        System.out.println(Child1.a);
        System.out.println(Child1.b);
    }

}

class Parent1 {
    public static int a = 5;

    static {
        System.out.println("Parent1 static block invoke!");
    }
}

class Child1 extends Parent1{
    public static int a = 7;

    public static int b = 9;

    static {
        System.out.println("Child1 static block invoke!");
    }
}
/**
 *  此示例验证了: 类的连接过程中的准备阶段 先于 类的初始化:
 *  类先将类变量在准备阶段赋默认值 ,然后在初始化阶段设置成初始值
 */
public class Test2 {

    public static void main(String[] args) {
//        Singleton.getInstance();
        System.out.println("a = "+ Singleton.a);
        System.out.println("b = "+ Singleton.b);
        System.out.println("c = "+ Singleton.c);
    }

}

class Singleton {

    public static int a;

    public static int b = 3;

    static {
        System.out.println("satic block a = "+ a);
        System.out.println("static blck b = "+ b);
    }

    public static Singleton singleton = new Singleton();

    private Singleton() {
        a++;
        b++;
        c++;
    }

    public static int c = 0;

    public static Singleton getInstance() {
        return singleton;
    }

}
/**
 * 1. 创建对象时,先执行静态代码块,然后执行代码块,最后执行其构造方法
 * 2. 类的静态代码只有在类的初始化被执行(对应类对象在jvm只有一个),只能执行一次,
 *  而类的代码块与构造方法直接与类的实例绑定在一起,创建几个实例,就会执行几次
 *  3. 类的主动使用会导致类的初始化:
 *      主动使用有: new 一个类的实例, 调用类的反射,访问类的静态变量或将静态变量庙会,调用类的静态方法,初始化一个类的子类,启动类main 方法所有类, JDK 1.7以后动态语言的调用
 */
public class Test0 {

    public static void main(String[] args) {
//        System.out.println(Test00.a);//调用类的静态变量时,会导致类的初始化
       Test00 t = new Test00();

        Test00 t1 = new Test00();
    }


}

class Test00 {

    public static int a = 1;

    public int b ;

    public int c = 5;

    static {
        System.out.println("static code block invoke!");
    }
  
    {
        System.out.println("code block invoke!");//只有类的实例化时,才会执行
    }

    public Test00(){
        System.out.println(b);
        System.out.println("contract mothod invoke!");
        System.out.println(c);
    }
}