Java类的加载
对于子类有继承父类,然后创建子类的对象时类的加载过程
首先创建子类对象之前需要加载类,在有父类的情况下会先加载父类
第一先加载父类中的静态元素,先加载静态属性,再加载静态方法,再加载静态块,加载完之后就会去加载子类的静态成员,块中可以有执行的方法,如果有执行方法,会先执行完方法再去加载子类(静态块中只能是静态方法,因为静态成员不能调用非静态成员,原因就是静态成员加载之前非静态成员还没有加载,所以静态成员无法调用非静态成员)
第二加载子类中的静态成员(顺序:属性、方法、块),加载完成后会去加载父类的非静态成员
第三加载父类中的非静态元素(顺序:属性、方法、块、构造方法),然后加载子类的非静态成员
第四加载子类的非静态元素(顺序:属性、方法、块、构造方法),所有的元素都加载完成后才可以创建对象
父类
package test;
public class Animal {
public int a = 100;//第七加载父类的非静态属性
public static int b = 200;//第一加载父类的静态属性
{//第九加载父类的非静态块
this.eatAnimal();
System.out.println("6:Animal中的块"+this.a);
}
//第一执行父类的静态块中的代码
static {//第三加载父类的静态块然后加载子类的静态内容(静态属性、方法、块)
Animal.sleep();
System.out.println("2:Animal中的静态块"+Animal.b);
}
public Animal() {/*第十加载父类的构造方法(子类无说明super(xxx),就加载父类的无参,有说明按照子类中的来)然后加载子类的非静态元素*/
System.out.println("7:Animal的构造方法");
}
public void eatAnimal() {//第八加载父类的非静态方法
System.out.println("5:Animal中的eat方法");
}
public static void sleep() {//第二加载父类的静态方法
System.out.println("1:Animal中的静态sleep方法");
}
}
子类
package test;
public class Person extends Animal {
public int a = 10;//第十一加载子类的非静态属性
public static int b = 20;//第四加载子类的静态属性
{//第十三加载子类的非静态块
this.eat();
System.out.println("9:Person中的块"+this.a);
}
static {//第六加载子类的静态块,然后子类开辟空间,先加载父类的非静态内容(属性、方法、块、构造方法)
Person.sleep();
System.out.println("4:Person中的静态块"+Person.b);
}
public Person() {//第十四子类的所有内容都加载完了加载构造方法
System.out.println("10:Person的构造方法");
}
public void eat() {//第十二加载子类的非静态方法
System.out.println("8:Person中的eat方法");
}
public static void sleep() {//第五加载子类的静态方法
System.out.println("3:Person中的静态sleep方法");
}
}
测试方法
package test;
public class Test {
public static void main(String[] args) {
new Person();
}
}
执行结果
1:Animal中的静态sleep方法
2:Animal中的静态块200
3:Person中的静态sleep方法
4:Person中的静态块20
5:Animal中的eat方法
6:Animal中的块100
7:Animal的构造方法
8:Person中的eat方法
9:Person中的块10
10:Person的构造方法