我不是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”将首先打印,因为它在超类中,private static B objB = new B();
将在它之后初始化(实例初始化器,然后是构造函数)。
我们在控制台中获得3AD
。
然后main方法运行并创建一个D类的新实例,确定。
但是从这一步开始,命令很奇怪:
1 超类public C() { System.out.print("P"); }
3ADP
。
2 然后D.class私人的字段A objA = new A();
控制台中的 3ADPO
。
3 D.class的构造函数是最后一个,所以:
控制台中的 3ADPOT
。
所以问题是:为什么超类构造函数在子类的字段之前运行?我认为构造函数的优先级最低。任何人都可以在docs上分享链接吗?
答案 0 :(得分:0)
如果我们认为那么很容易理解,首先子类继承自超类,然后只能覆盖行为或访问超类中定义的属性。
每当我们创建一个类A
的对象时,首先检查该类是否已加载,如果没有,则加载它,如果它存在则调用其静态initilizer,然后启动所有静态字段(使用默认值或定义的值)。调用此超级构造函数后,将设置由超类设置的所有属性。然后启动所有实例字段,最后执行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();
}
}