java - 初始化的棘手顺序

标签 java initialization

我不是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/

相关文章:

java - Spring 安全中每个请求的不同 csrf token

Java 使用 .jar 文件中的图像

c# - 如何初始化字典数组

c++ - 无法使用指向其他结构的嵌套指针初始化结构

java - 关于 Android 开发 IDE 和框架

java - 从 dv 摄像机进行实时 RTMP 流传输的最佳方式

java - 如何从html(从jsp转换而来)中删除jsessionid

javascript - 从 json 对象初始化 Typescript 中的 Map<string,string>

Java - 为什么这个初始化不起作用?

java - 构造函数是如何执行的?