gpt4 book ai didi

java - 构建/初始化的顺序?

转载 作者:行者123 更新时间:2023-12-01 19:27:14 26 4
gpt4 key购买 nike

注意:我添加了 android 标记,因为我只在 Android 自己的虚拟机上尝试过此操作,作为应用程序的一部分。其他 JVM 的行为方式可能相同,也可能不同。

<小时/>

这是我的代码的简化版本:

public class Test {
public static class Base {
public final Object base = new Object();

public Base() {
print();
}

public void print() {
System.err.println(String.format("base = %s", base));
}
}

public static class Outer extends Base {
public final Object member = new Object();

public Outer() {
super();
}

@Override
public void print() {
super.print();
System.err.println(String.format("member = %s", member));
}
}

public static void main(String[] args) {
new Outer();
}
}

输出:

base = java.lang.Object@9a9e0fa
member = null

为什么member为NULL?我的印象是任何非静态类字段都会在构造函数运行之前初始化。

最佳答案

I was under the impression any nonstatic class fields are initialized before the constructor runs.

您的印象不正确。

实际发生的情况是,对象的所有父类(super class)初始化发生在该对象的任何子类初始化之前。

上述经验法则仅适用于对象实例初始化。类(即static)初始化有点复杂。但这个问题是关于实例初始化的。

该过程在JLS 12.5中有详细描述。 。相关部分是这样的:

Just before a reference to the newly created object is returned as the result, the indicated constructor is processed to initialize the new object using the following procedure:

  1. Assign the arguments for the constructor to newly created parameter variables for this constructor invocation.

  2. If this constructor begins with an explicit constructor invocation (§8.8.7.1) of another constructor in the same class (using this), then evaluate the arguments and process that constructor invocation recursively using these same five steps. If that constructor invocation completes abruptly, then this procedure completes abruptly for the same reason; otherwise, continue with step 5.

  3. This constructor does not begin with an explicit constructor invocation of another constructor in the same class (using this). If this constructor is for a class other than Object, then this constructor will begin with an explicit or implicit invocation of a superclass constructor (using super). Evaluate the arguments and process that superclass constructor invocation recursively using these same five steps. If that constructor invocation completes abruptly, then this procedure completes abruptly for the same reason. Otherwise, continue with step 4.

  4. Execute the instance initializers and instance variable initializers for this class, assigning the values of instance variable initializers to the corresponding instance variables, in the left-to-right order in which they appear textually in the source code for the class. If execution of any of these initializers results in an exception, then no further initializers are processed and this procedure completes abruptly with that same exception. Otherwise, continue with step 5.

  5. Execute the rest of the body of this constructor. If that execution completes abruptly, then this procedure completes abruptly for the same reason. Otherwise, this procedure completes normally.

请注意我突出显示的句子。当您在其余部分的上下文中考虑这一点时,这意味着 Base() 的构造函数主体在 Outer 的实例字段初始化之前运行。

<小时/>

Other JVMs might or might not behave the same way.

事实上,所有 JVM 都应该这样做。这就是 Java 语言被指定的行为方式。

关于java - 构建/初始化的顺序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61134777/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com