2017-04-11 51 views
0

我在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

然后主要方法运行并创建一个D类的新实例,它的确定。

但是因为该步骤的顺序是奇怪:

的超 public C() { System.out.print("P"); }

在控制台3ADP

构造函数。

然后字段D.class private A objA = new A();

3ADPO在控制台中。

而D.class的构造函数是最后,所以:

控制台3ADPOT

所以问题是:为什么超类构造函数在子类的字段之前运行?我认为建设者的优先级最低。任何人都可以在文档PLZ上分享链接?

回答

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(); 
    } 
} 
+1

我明白了,谢谢兄弟) – DontPanic