java没有规定类加载的时机,但是规定了类初始化的时机,一般认为类初始化的时候就加载。
一、类初始化的时机
1.创建类的实例,也就是new一个对象

2.访问某个类或接口的静态变量和静态方法 (直接用类名访问,没有new一个实体对象),注意访问类的静态域所导致的初始化,只初始化这个类,不会初始化这个类的父类。

3.反射(Class.forName(“com.lyj.load”)) 比如类Class中的方法或者java.lang.reflect包的方法对类进行反射调用的时候, 如果类没有进行过初始化 , 则需要先触发其初始化。

4…初始化一个类的派生类(会首先初始化子类的父类),只有在父类还没有初始化的时候,子类初始化才会让父类初始化。注意接口的初始化不会让父接口也初始化。

5.JVM启动时标明的启动类,即文件名和类名相同的那个类

Animal a = new Animal;
System.out.println(Person.name);
System.out.println(Person.shout());
Son s =  new Son();

二、类初始化的顺序
初始化顺序有以下几个原则:
1.超类初始化早于子类。
2.静态变量和成员方法初始化早于非静态方法和变量,但是静态域只初始化一次。
3.没使用的类根本不会被初始化,因为他没有被使用
4.在类的加载过程中,只有内部的变量和代码块创建完,才会去执行这个类的构造方法(除了static的方法,其他的方法都是在被调用的时候才会执行,只有构造方法会自己执行,所以等变量和代码块创建完,再调用构造方法加载各种函数)。
注意:这里说的代码块,是类中没有写成方法的代码块,相当于一个default的变量,比如下面例子A中的"A codeblock"那一句。

package test_demo;
public class test_shunxu {
    public static void main(String[] args) {
        A a = new A();
    }
}


class A{
    B b = new B();
    static{
        System.out.println("A static");
    }
    {System.out.println("A codeblock");}
    public A() {
        System.out.println("A()");
    }
}
class B{
    C c = new C();
    D d = new D();
    static{
        System.out.println("B static");
    }
    public B() {
        System.out.println("B()");
    }
}
class C{
    static{
        System.out.println("C static");
    }
    public C() {
        System.out.println("C()");
    }
}
class D{
    static{
        System.out.println("D static");
    }
    public D() {
        System.out.println("D()");
    }
}

结果:
A static
B static
C static
C()
D static
D()
B()
A codeblock
A()



package xing.test.thinking.chap7;
class A{
    static{
        System.out.println("A static");
    }
}
class B extends A{
    static{
        System.out.println("B static");
    }
}
class C extends B{
    private static D d = new D();
    static{
        System.out.println("C static");
    }
}
class D{
    static{
        System.out.println("D static");
    }
}
public class ExtendTest {
    public static void main(String[] args) {
        C c = new C();
    }
}

结果:
A static
B static
D static
C static

结论1:父类的静态代码块->子类的静态代码块->初始化父类的属性值/父类的普通代码块(自上而下的顺序排列)->父类的构造方法->初始化子类的属性值/子类的普通代码块(自上而下的顺序排列)->子类的构造方法。
结论2:静态资源在类的初始化中只会执行一次。
结论3:在结论2的基础上,非静态资源会随对象的创建而执行初始化。每创建一个对象,执行一次初始化。