gpt4 book ai didi

java - 解释java编译顺序

转载 作者:行者123 更新时间:2023-11-29 04:45:15 25 4
gpt4 key购买 nike

v2第一次进入A的c'tor时是null,但是如果我把v2的声明&初始化放在instance之前> 它会有一个值(value);这是为什么?

public class A {

private static final String v1 = new String(new byte[]{'a', 'b'});

private static A instance = new A();

private static final String v2 = new String(new byte[]{'b', 'c'});

private A() {
System.out.printf("A c'tor\tv1 [%s]\tv2 [%s]\n", v1, v2);
}

public static void main(String[] args) {
System.out.println("start main");
new A();
System.out.println("end main");
}
}

输出:

    A c'tor v1 [ab] v2 [null]
start main
A c'tor v1 [ab] v2 [bc]
end main

此外,如果我将 v2 的初始化更改为:

private static final String v2 = "ab";

它确实初始化了 v2,输出是:

A c'tor v1 [ab] v2 [ab]
start main
A c'tor v1 [ab] v2 [ab]
end main

编辑

第二部分的另一个测试:

public class A {

private static final String v1 = new String(new byte[]{'a', 'b'});

private static transient A instance = new A();

private static final String v2 = new String(new byte[]{'b', 'c'});
private static final String v3 = new String("ab");
private static final String v4 = "ab";

private A() {
System.out.printf("A c'tor\tv1 [%s] v2 [%s] v3 [%s] v4 [%s]\n", v1, v2, v3, v4);
}

public static void main(String[] args) {
System.out.println("start main");
new A();
System.out.println("end main");
}
}

输出:

A c'tor v1 [ab] v2 [null] v3 [null] v4 [ab]
start main
A c'tor v1 [ab] v2 [bc] v3 [ab] v4 [ab]
end main

最佳答案

初始化类 A 时(在执行 main 之前),静态变量按照它们在源文件中出现的顺序进行初始化。

  • 第一个 v1
  • then instance(打印 A c'tor v1 [ab] v2 [null] 因为它的初始化涉及创建 A 的实例)- 它在 v2 之前初始化,这就是 v2 仍然是 null 的原因。
  • 然后是 v2

初始化后,main 方法被执行,并产生接下来的 3 行输出。在 main 方法中创建 A 的新实例会产生与先前构造函数调用不同的输出,因为此时 v1v2 已初始化。

编辑:

关于您更新的问题:

如果您关注initialization procedure in JLS 12.4.2 :

  1. Otherwise, record the fact that initialization of the Class object for C is in progress by the current thread, and release LC. Then, initialize the final class variables and fields of interfaces whose values are compile-time constant expressions.

...

  1. Next, execute either the class variable initializers and static initializers of the class, or the field initializers of the interface, in textual order, as though they were a single block.

如你所见,最终的静态变量的值为compile-time constant expressions在其余的静态变量之前被初始化。因此,将 v2 的值更改为常量 "ab" 会导致 v2instance 变量之前被初始化,这解释了不同的输出。

关于java - 解释java编译顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37439450/

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