静态初始化块未按预期工作

Static initializing block is not working as expected

我有两个 类,“Test1”和“Test0”,如代码所示。

public class Test1 {
    public static void main(String...args) {
        System.out.print(Test0.randomName);
    }
}
public class Test0 {
    public static String randomName = initRandomName();
    private static String string0;
    
    static {
        string0 = "George";
    }
    private static String initRandomName() {
        return "Mr. "+string0;
    }
}

我以为它会打印 Mr. George 但它打印的是 Mr. null。 我不明白发生了什么。请帮助我。谢谢。

JLS 12.4.2 详细介绍了初始化过程。特别是:

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.

换句话说,你可以想象你的Test0 class是这样写的:

public class Test0 {
    public static String randomName;
    private static String string0;
    
    static {
        randomName = initRandomName();
        string0 = "George";
    }

    private static String initRandomName() {
        return "Mr. " + string0;
    }
}

所以当initRandomName()执行的时候,string0还是null。

可以 randomName 字段的初始化移动到静态初始化程序之后,如下所示:

class Test0 {
    private static String string0;

    static {
        string0 = "George";
    }

    public static String randomName = initRandomName();

    private static String initRandomName() {
        return "Mr. "+string0;
    }
}

...但这很脆弱,依赖于没有人在不了解影响的情况下重新排序 class 的成员。

如果您真的需要这样的初始化,我建议声明所有字段而不初始化它们,然后在静态初始化程序块中初始化 所有内容,这样顺序就很明显了。