读取间接状态与在java中读取变量的直接状态

问题描述 投票:0回答:1

在下面的代码编译中,静态块内的static变量j失败,如注释中所述。

但是,它在m1()方法中运行良好

class StaticBlock {
    static {
        m1();
        //compilation fails because variable are in read indirect state
        System.out.println(j);
    }

    static void m1() {
        System.out.println(j);
    }

    static int j = 10;

我知道编译失败的根本原因 - 变量j处于读取间接状态。

我的问题 - 为什么这种行为,我们也可以像在0中那样在静态块内打印m1()

是什么让API开发人员产生了这种差异

java static
1个回答
1
投票

为什么这种行为,我们也可以在0中打印静态块内的m1()

是什么让API开发人员产生了这种差异

在类初始化期间,对于事件顺序的简单规范,常量(即final)类字段的一致性,程序员期望和易于实现,存在竞争优先级。

常数字段的值提供了一个很好的起点。 Java希望避免这些字段的默认值是可观察的,特别是要避免在其他类变量的初始化中使用它们的默认值。因此,首先在静态初始化程序块或其他类变量的初始化程序之前初始化它们。它们按照它们出现在源代码中的顺序进行初始化,这是一个易于人类和编译器理解的规则。但是,这提供了一个类变量的初始化器看到另一个类变量的默认值的可能性,从而产生令人惊讶的,不需要的结果。因此,Java指定必须在编译时检测并拒绝该情况。

静态初始化程序块和其他类变量的初始化程序随后按照它们在源代码中出现的顺序执行。你要问的约束的情况在这里并不那么强烈,但是通过在这里应用与类常量相同的规则来选择一致性是合理的。结合起来,效果是易于理解和预测初始化顺序,这也与在评估静态初始化程序块之前评估和分配的类变量初始化程序的模型大致一致。

但接下来是静态方法。非常希望静态方法在初始化期间可用,但是在初始化完成之后,当初始化顺序考虑因素都不相关时,它们也是可用的。因此,根据源代码中的外观顺序限制静态方法对变量的访问是不可行的。可以想象,VM可能需要通过编译时的控制流分析或某种形式的运行时监控来跟踪类变量的各个初始化状态,而不是要求这样的复杂性,Java选择简单,允许人们谁坚持弄乱(通过观察类变量的默认值)这样做。

最后,我强调,所谓的“Read Indirect Write Only状态”是第三方模型的一部分,它是如何工作的。 Java本身没有这样的概念 - 当涉及对静态方法使用类变量的要求时,这样的事情正是它拒绝支持简单性的东西。

© www.soinside.com 2019 - 2024. All rights reserved.