我们知道在对象创建之前,一定会先加载类,如果类中包含有静态元素(属性和方法),一定会先加载静态元素,然后再开始创建对象。创建对象无非是调用了构造方法,在创建对象之前,如果定义了块,一定会先执行程序块,如果有static修饰的静态块,那么静态块会比普通块先执行。
在有继承关系的对象创建过程中,问题稍稍变得复杂起来,子类对象在调用构造方法创建子类对象之前,会先调用父类的构造方法。因此父类比子类加载的要早。
java的类加载机制其实是个很复杂的问题,我这里的对象创建过程有的地方其实还不对,但从理解层面来讲,这个顺序基本是讲的通的。
public class Animal {
public String test = "AnimalField";
public static String testStatic = "AnimalStaticField";
public Animal(){
System.out.println("我是animal中默认无参数的构造方法");
}
{
this.testAnimal();
System.out.println("我是animal中的普通程序块"+test);
}
static {
testStatic();
System.out.println("我是animal类中静态程序块"+testStatic);
}
public void testAnimal(){
System.out.println("我是animal类中的普通方法");
}
public static void testStatic() {
System.out.println("我是animal类中的静态方法");
}
}
public class Person extends Animal{
public String test = "personField";
public static String testStatic = "personStaticField";
public Person(){
System.out.println("我是person中默认无参数的构造方法");
}
{
this.testPerson();
System.out.println("我是person中的普通程序块"+test);
}
static {
testStatic();
System.out.println("我是person类中静态程序块"+testStatic);
}
public void testPerson(){
System.out.println("我是person类中的普通方法");
}
public static void testStatic() {
System.out.println("我是person类中的静态方法");
}
}
public class Test {
public static void main(String[] args) {
Person person = new Person();
}
}
输出结果:
总结来说java类加载的顺序以及对象的创建过程为:(前4步是类加载顺序)
- 加载父类的类模板
- 父类会产生自己的静态空间(静态属性,静态方法,静态块,执行静态块)
- 加载子类的类模板
- 子类会产生自己的静态空间(静态属性,静态方法,静态块,执行静态块)
- 开辟对象空间
- 加载父类的非静态成员(属性,方法,块,构造方法)
- 执行父类的块,执行父类的构造方法
- 加载子类的非静态成员(属性,方法,块,构造方法)
- 执行子类的块,执行子类的构造方法
说明:
- 类模板里存放的只是类的信息,不会执行,然而在产生静态空间时,静态块会执行(程序块是默认执行的)。
- 实际上在底层加载时先加载的,执行会统一执行。
java学习的小白一个,若写的有什么不对的地方,欢迎批评否证。