我不是java新手,但我有一个让我困惑的例子。 这是:
class A {
public A() { System.out.print("O"); }
}
class B {
{ System.out.print("A"); }
public B() { System.out.print("D"); }
}
class C {
static { System.out.print("3"); }
public C() { System.out.print("P"); }
}
public class D extends C {
private A objA = new A();
private static B objB = new B();
public D() { System.out.print("T"); }
public static void main(String[] args){
new D();
}
}
那么system.out中的结果是什么?
我们知道静态成员是第一个,因此“3”将首先打印,因为它位于父类(super class)中,并且 private static B objB = new B();
将在其之后初始化(实例初始值设定项,然后是构造函数)。
我们在控制台中看到 3AD
。
然后main方法运行,创建一个新的D类实例,就ok了。
但是从这一步开始,顺序就很奇怪:
1 父类(super class)的构造函数 public C() { System.out.print("P"); }
控制台中的3ADP
。
2 那么 D.class 的字段 private A objA = new A();
3ADPO
在控制台中。
3 D.class 的构造函数是最后一个,所以:
3ADPOT
在控制台中。
所以问题是:为什么父类(super class)的构造函数在子类的字段之前运行?我认为构造函数的优先级最低。谁能分享一下文档链接吗?
最佳答案
简单来说,如果我们认为那么很容易理解,首先子类继承自父类(super class),然后它只能覆盖父类(super class)中定义的行为或访问父类(super class)中定义的属性。
每当我们创建类 A
的对象时,首先检查该类是否已加载,如果没有,则加载该类,如果存在,则调用其静态初始化程序,然后初始化所有静态字段(使用默认值或定义的值)。调用此 super 构造函数后,将设置父类(super class)设置的所有属性。然后所有实例字段都被初始化,最后执行A
的构造函数代码。
下面是执行顺序。
public class A{
static{
// 1
}
int x = 30; // 3
public A(){
//4
}
}
public class B extends A{
static{
//2
}
private int s = 60; //5
public B(){
//6
}
}
public class Test {
public static void main(String[] args){
new B();
}
}
关于java - 初始化的棘手顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43355199/