浅谈Java中父类与子类的加载顺序详解
在Java中,当我们定义了一个类时,JVM会按照一定的顺序进行类的加载。这个加载的过程中包含了类的初始化、父子类的加载、静态成员变量的赋值等内容。父类与子类的加载顺序是其中一项比较重要的内容。下面我们就来详细讲解一下Java中父类与子类的加载顺序。
父类的加载顺序
父类的加载顺序总是在子类之前。当我们定义一个子类时,如果没有明确指定父类,则默认继承Object类。父类的加载顺序依次为:
- 加载父类的静态变量,包括静态方法;
- 父类初始化;
- 子类加载。
例如,我们有如下的父类:
public class Parent {
public static String parentStr = "Parent static variable";
static {
System.out.println(parentStr);
System.out.println("Parent static code block!");
}
public Parent() {
System.out.println("Parent constructor!");
}
}
当我们定义一个子类并实例化时,父类的静态变量和静态代码块会最先被加载执行,并依次输出"Parent static variable"和"Parent static code block!"。随后进行父类的初始化,输出"Parent constructor!"。最后进行子类的加载、初始化等操作。
子类的加载顺序
子类在继承了父类之后,会在父类初始化完成之后进行加载。子类的加载顺序依次为:
- 加载子类的静态变量,包括静态方法;
- 子类初始化。
例如,我们有如下的子类:
public class Child extends Parent {
public static String childStr = "Child static variable";
static {
System.out.println(childStr);
System.out.println("Child static code block!");
}
public Child() {
System.out.println("Child constructor!");
}
}
当我们实例化子类时,首先会加载子类的静态变量和静态代码块,依次输出"Child static variable"和"Child static code block!"。随后进行子类的初始化,输出"Child constructor!"。
需要注意的是,如果我们定义了多层的继承关系,那么类的加载顺序同样遵循父类优先的原则。
示例说明
接下来,我们来看一下具体的示例说明。
示例一
public class Parent {
public static String parentStr = "Parent static variable";
static {
System.out.println(parentStr);
System.out.println("Parent static code block!");
}
public Parent() {
System.out.println("Parent constructor!");
}
}
public class Child extends Parent {
public static String childStr = "Child static variable";
static {
System.out.println(childStr);
System.out.println("Child static code block!");
}
public Child() {
System.out.println("Child constructor!");
}
}
public class TestClass {
public static void main(String[] args) {
Child child = new Child();
}
}
运行以上的代码,输出如下:
Parent static variable
Parent static code block!
Parent constructor!
Child static variable
Child static code block!
Child constructor!
从输出结果中可以看出,先执行了父类的静态变量和静态代码块,输出"Parent static variable"和"Parent static code block!",然后进行了父类的初始化,输出"Parent constructor!"。随后执行了子类的静态变量和静态代码块,输出"Child static variable"和"Child static code block!",然后进行了子类的初始化,输出"Child constructor!"。
示例二
public class Parent {
public static String parentStr = "Parent static variable";
static {
System.out.println(parentStr);
System.out.println("Parent static code block!");
}
public Parent() {
System.out.println("Parent constructor!");
}
}
public class Child extends Parent {
public static String childStr = "Child static variable";
public static void print() {
System.out.println("Child static method!");
}
static {
System.out.println(childStr);
System.out.println("Child static code block!");
}
public Child() {
System.out.println("Child constructor!");
print();
}
}
public class TestClass {
public static void main(String[] args) {
new Child();
}
}
运行以上的代码,输出如下:
Parent static variable
Parent static code block!
Parent constructor!
Child static variable
Child static code block!
Child constructor!
Child static method!
从输出结果中可以看出,先执行了父类的静态变量和静态代码块,输出"Parent static variable"和"Parent static code block!",然后进行了父类的初始化,输出"Parent constructor!"。随后执行了子类的静态变量和静态代码块,输出"Child static variable"和"Child static code block!",然后进行了子类的初始化,输出"Child constructor!"。子类的构造方法print()输出"Child static method!"。
结论
在Java中,父类总是先于子类进行加载。父类的静态变量和静态代码块会最先被加载执行,然后进行父类的初始化,最后进行子类的加载、静态变量和代码块的加载、子类的初始化。需要注意的是,子类的构造方法也是在它的静态方法和静态代码块执行完之后才会执行。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:浅谈Java中父类与子类的加载顺序详解 - Python技术站