类加载的顺序:
1、加载静态成员\代码块:(静态变量、静态块按书写先后顺序执行)
先递归地加载父类的静态成员/代码块(Object的最先),再依次加载到本类的静态成员。
同一个类里的静态成员\代码块,按写代码的顺序加载。如果其间调用静态方法,则调用时会先运行静态方法,再继续加载。同一个类里调用静态方法时,可以不理会写代码的顺序。
调用父类的静态成员,可以像调用自己的一样,但调用其子类的静态成员,必须使用(子类名.成员名)来调用。
2、加载非静态成员/代码块(非静态变量、非静态块按书写先后顺序执行)(实例块在创建对象时才会被加载,而静态成员在不创建对象时就被加载):先递归地加载父类的非静态成员/代码块(Object的最先)然后调用父类的构造函数,再依次加载到本类的非静态成员/代码块,然后构造函数。
class Base
{
public static int a = 10;//第一步
public int b = 20;//第十步
static
{
System.out.println("1.Static Init Base" + a);//第二步
}
public Base()//第十一步
{
System.out.println("6.Init Base" + this.b);
}
}
//一级子类和基类包含的内容一样
class SuperClass extends Base
{
//静态变量、静态块执行按书写先后顺序
public static int a1 = getSuperStaticNumber();//第三步
public int b1 = getSuperInstanceNumber();//第十二步
public SuperClass()//第十四步
{
System.out.println("8.Init SuperClass" + this.b1);
}
static//第五步
{
System.out.println("3.Static Init SuperClass");
}
public static int getSuperStaticNumber()//第四步
{
System.out.println("2.Static member init");
return 100;
}
public int getSuperInstanceNumber()//第十三步
{
System.out.println("7.Instance member init");
return 200;
}
}
//二级子类为测试该代码的驱动类
public class Sub extends SuperClass
{
public static int a2 = getStaticNumber();//第六步
public int b2 = getInstanceNumber();//第十五步
public Sub()//第十七步
{
System.out.println("10.Init SubClass" + this.b2);
}
public static int getStaticNumber()//第七步
{
System.out.println("4.Static member init Sub");
return 1000;
}
public int getInstanceNumber()//第十六步
{
System.out.println("9.Instance member init Sub");
return 2000;
}
static//第八步
{
System.out.println("5.Static Init" + a2);
}
public static void main(String[] args)//第九步
{
new Sub();
}
}
执行结果: