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;