Java中的静态控制流
当我们运行包含静态变量、方法和块的Java类时,静态控制流决定了将按顺序执行的活动/步骤的顺序。本文将解释每当执行Java程序时,静态控制流是如何发生的。
先决条件:静态块
静态控制流机制按确切的时间顺序执行以下 3 个步骤:
- 从上到下识别静态构件。在此步骤中识别所有静态变量、方法和块。
- 从上到下执行静态变量赋值和静态块。
- 最后在静态控制流程的最后一步执行静态main方法。
例子:
Java
// StaticControlFlow class (Main class)
class StaticControlFlow {
// initializing static integer a=100
static int a = 100;
// static main method
public static void main(String[] args)
{
// calling static method print()
print();
System.out.println(
"Main method has finished its execution");
}
// first static block
static
{
// displaying value of a
System.out.println(a);
// calling static method print()
print();
System.out.println("Inside First Static Block");
}
// static method print()
public static void print()
{
// displaying value of b
System.out.println(b);
}
// second static block
static
{
System.out.println("Inside Second Static Block");
}
// initializing static integer b=200
static int b = 200;
}
Java
// Java program to demonstrate the
// working of RIWO state in Java
class Riwo {
static int i = 10;
static
{
m1();
System.out.println("block1");
}
public static void main(String[] args)
{
m1();
System.out.println("block main");
}
public static void m1()
{
System.out.println(j);
System.out.println("block m1");
}
static int j = 20;
static {
System.out.println("end of code");
}
}
Java
// Java program to demonstrate the error
// while working of RIWO state in Java
class Riwo {
static
{
System.out.println(i);
System.out.println("block1");
}
static int i = 10;
public static void main(String[] args)
{
System.out.println("main block");
}
}
100
0
Inside First Static Block
Inside Second Static Block
200
Main method has finished its execution
说明:上述程序执行时,静态控制流机制会依次执行这3个步骤。在第一步中识别出静态成员后,两个静态块都从上到下执行。在第一个静态块中,变量“a”的值为 100,因为它在执行第一个静态块之前已被初始化。
但是,在第二个静态块中,变量“b”的值尚未按照静态控制流进行初始化。因此,JVM 将打印 0 作为未初始化静态变量的默认值。
然后,在第三步也是最后一步中,将执行静态 main 方法。在 main 方法中,再次调用静态方法 print(),这一次它打印 b = 200,因为变量 'b' 在第二步中被初始化。
直接和间接参考
如果我们尝试读取并显示静态块内的变量值,则该读取操作称为直接读取。如果我们从静态块中调用方法,并且在该方法中,如果我们尝试读取变量,则该读取操作称为间接读取。
在上面的示例中,在第一个静态块中打印变量“a”的值时,它被认为是直接读取操作。但是,在同一个静态块中调用静态方法 print(),并打印变量“b”的值。这被认为是间接读取操作。
假设一个变量由 JVM 识别,但尚未由其原始值初始化。在这种情况下,变量被称为处于只读间接只写 (RIWO) 状态。在静态控制流程的第一步之后,变量“a”和“b”都处于 RIWO 状态。
日沃状态
当一个Java类被执行时,有几个步骤,JVM 依次执行几个步骤。
- 从上到下识别静态成员。
- 从上到下执行静态变量赋值和静态块。
- 执行主要方法。
在这些阶段中,静态变量存在一种称为 RIWO(仅读取间接写入)的状态。
在 RIWO 期间,不能通过引用直接访问变量。相反,我们需要使用间接的方式来调用某些变量。
例如:
class Riwo {
static int i = 10;
static {
System.out.println(i);
}
}
在上述情况下,输出为 10。
Java
// Java program to demonstrate the
// working of RIWO state in Java
class Riwo {
static int i = 10;
static
{
m1();
System.out.println("block1");
}
public static void main(String[] args)
{
m1();
System.out.println("block main");
}
public static void m1()
{
System.out.println(j);
System.out.println("block m1");
}
static int j = 20;
static {
System.out.println("end of code");
}
}
0
block m1
block1
end of code
20
block m1
block main
Java
// Java program to demonstrate the error
// while working of RIWO state in Java
class Riwo {
static
{
System.out.println(i);
System.out.println("block1");
}
static int i = 10;
public static void main(String[] args)
{
System.out.println("main block");
}
}
输出:在上述情况下,我们得到以下编译时错误
prog.java:7: error: illegal forward reference
System.out.println(i);
^
1 error
这意味着我们不能直接读取处于 RIWO 状态的静态变量。我们应该使用方法间接调用变量。