下面我将详细讲解Java父类和子类初始化顺序的深入理解。
父类和子类初始化顺序的基本概念
在Java中,对象的初始化包括两部分:静态初始化和实例初始化。当类被加载时,它的静态成员会被初始化;当类的对象被创建时,会调用构造函数进行实例初始化。父类和子类的初始化顺序如下:
- 父类的静态成员初始化
- 子类的静态成员初始化
- 父类的实例成员初始化
- 父类的构造函数初始化
- 子类的实例成员初始化
- 子类的构造函数初始化
示例说明一
我们考虑下面的代码:
class A {
static {
System.out.println("A的静态代码块");
}
{
System.out.println("A的实例代码块");
}
public A() {
System.out.println("A的构造函数");
}
}
class B extends A {
static {
System.out.println("B的静态代码块");
}
{
System.out.println("B的实例代码块");
}
public B() {
System.out.println("B的构造函数");
}
}
public class Test {
public static void main(String[] args) {
new B();
}
}
输出:
A的静态代码块
B的静态代码块
A的实例代码块
A的构造函数
B的实例代码块
B的构造函数
这样的输出结果是符合我们上面说的初始化顺序的。你可以看到,在对象实例化前,父类的静态变量会被初始化,然后是子类的静态变量初始化。接下来,父类的实例成员变量初始化,执行父类的构造函数;然后是子类的实例成员变量初始化和子类的构造函数。
示例说明二
下面再来一个例子,考虑子类是继承了父类的构造函数:
class A {
public A() {
System.out.println("A的构造函数");
method();
}
public void method() {
System.out.println("A的method方法");
}
}
class B extends A {
private int a = 1;
public void method() {
System.out.println("B的method方法,a = " + a);
}
public B() {
System.out.println("B的构造函数");
}
}
public class Test {
public static void main(String[] args) {
new B();
}
}
输出:
A的构造函数
B的method方法,a = 0
B的构造函数
在这个例子中,我们可以看到,虽然在父类的构造函数中调用了method方法,但是由于这个方法被子类override了,在父类构造函数调用时,实际上是调用了子类的方法。由于子类的成员变量还没有被初始化,所以a的值为0。
这里提醒一下,最好不要在父类构造函数中调用被子类override的方法,否则可能会出现一些奇怪的结果,因为子类的成员变量还没有被初始化。这就是父类和子类初始化顺序的一个比较容易出错的地方。
以上是关于Java父类和子类初始化顺序的深入理解,以及两个实例讲解。希望能对你有所帮助。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:java父类和子类初始化顺序的深入理解 - Python技术站