Java文件初始化顺序

Java文件初始化顺序,java,static,Java,Static,上述程序在i=3时未给出任何错误;但是当我们调用静态块的println()方法中的i时,它会显示错误 java:6:错误:非法转发引用 System.out.println(“你好,世界!”+i); ^ 1错误 但是如果像这样修改上面的程序,它将工作(首先加载静态变量),println方法中没有错误 class revi { static { i = 3; System.out.println("Hello World!" + i); }

上述程序在
i=3时未给出任何错误;但是当我们调用静态块的
println()
方法中的
i
时,它会显示错误

java:6:错误:非法转发引用 System.out.println(“你好,世界!”+i); ^ 1错误

但是如果像这样修改上面的程序,它将工作(首先加载静态变量),println方法中没有错误

class revi {

    static {
        i = 3;
        System.out.println("Hello World!" + i);
    }
    static int i = 15;

    public static void main(String[] args) {
        System.out.println("Hello World!");
    }
}

请解释内部流程…

这在第节中介绍:

有时,即使这些类变量在范围内(§6.3),但其声明在使用后以文本形式出现的类变量的使用受到限制。具体而言,如果以下所有条件均为真,则为编译时错误:

  • 类或接口C中的类变量声明在使用类变量后以文本形式出现

  • 在C的类变量初始值设定项或C的静态初始值设定项中使用一个简单的名称

  • 使用不在作业的左侧

  • C是包含该用法的最内层类或接口

在您的情况下,当您打印值时,所有这些都是真的,因此会出现错误


更改代码以移动声明后,第一个项目符号不再为真,因此它将编译。

在案例1中,您使用
3
初始化变量
i
,在第2行使用
15
初始化变量。所以最终结果是变量
i
保持
15

在案例2中,您将得到
非法正向引用错误
,因为您试图在定义变量之前使用变量
i
根据更新的未定义的静态变量只能在赋值中使用,除非它们以类名作为前缀(在这种情况下,它们会得到默认值)。例1

例如,2在这种情况下,您正在访问以类名为前缀的变量
i
。但是请记住,
revi.i
将具有值
0
而不是
15
,因此输出将是
0

static {
    i = 3;
    i = i * 2; // will give you compile error
    System.out.println("Hello World!" );
}


在案例3中,首先声明并初始化
i=5
,然后将3分配给它。因此,在初始化之后,
i
将保留3作为其值

当java类被执行时,JVM会按顺序执行几个步骤

从上到下标识静态成员。 从上到下执行静态变量分配和静态块。 执行main方法。 在这些阶段中,静态变量有一种称为RIWO(只读间接写)的状态

在RIWO过程中,变量不能通过其引用直接访问。相反,我们需要使用一种间接的方式来调用某些变量


您可以参考该链接以获取详细信息。

正如您所看到的:静态初始化块只能引用以前声明的静态变量。“它显示错误”永远不够信息。请告诉我们你看到了什么错误。你知道为什么他们决定写
i=3
不是非法的正向引用,而写入
System.out.println(i)是。有什么意思?@pbabcdefp:我真的不能告诉你。我怀疑这是因为前者不需要已知现有的值,而后者需要知道-这可能会更容易确定代码的发出顺序。不太清楚。你能再多说说第二个案子吗?为什么我们使用
revi.i
而不是
i
呢问题消失了
System.out.println(“你好,世界!”+revi.i)?我更感兴趣的是“为什么
revi.I
是允许的,而
I
不是”,而不是“它将如何工作”。IMO JLS只是证实了这一点,而不是解释。总有一天我们需要更仔细地观察。
class revi {

    static int i = 15;

    static {
        i = 3;
        System.out.println("Hello World!" + i);
    }

    public static void main(String[] args) {
        System.out.println("Hello World!");
    }
}
static {
    i = 3;
    i = i * 2; // will give you compile error
    System.out.println("Hello World!" );
}
static {
    i = revi.i * 2; // this line is similar to  revi.i = revi.i * 2;
    System.out.println("Hello World!" + revi.i );
}
static int i = 15;