Core Java上说,当类被调用时,该类的静态初始化块会被加载有且仅有一次,并且是在该类中所有其他语句执行之前加载,可是在下面这段代码中,有两个静态块,分别是在Scanner语句之前和之后加载的,为什么会这样呢?这样不是和书上说的矛盾了么?按书上说的,应该是两个块同时在其他语句执行之前加载的啊,请高手们指点
import java.util.*;class Test
{
public static void main(String[] args)
{
System.out.println("Test");
System.out.println(T.num);
}
}class T
{
static
{
System.out.println("之前加载");
}
static int n = new Scanner(System.in).nextInt();
public static final int num = n;
static
{
System.out.println("之后加载");
}
}控制台输入如下:
Test
之前加载
[BLUEJ Input Box]<--询问输入的对话框
之后加载
12
import java.util.*;class Test
{
public static void main(String[] args)
{
System.out.println("Test");
System.out.println(T.num);
}
}class T
{
static
{
System.out.println("之前加载");
}
static int n = new Scanner(System.in).nextInt();
public static final int num = n;
static
{
System.out.println("之后加载");
}
}控制台输入如下:
Test
之前加载
[BLUEJ Input Box]<--询问输入的对话框
之后加载
12
不仅静态块如此,静态变量也是。而且它们的初始化顺序由jvm决定(有可能是由上倒下);
static
{
System.out.println("之前加载");
}
static int n = new Scanner(System.in).nextInt();
public static final int num = n;
static
{
System.out.println("之后加载");
}
当程序运行到System.out.println(T.num);这句时,那么就进行对类T的加载--》连接--》初始化,
它运行完第一个static静态初始化块之后,发现第二条语句是一个阻塞式的语句,需要你输入一个数之后程序才能继续运行,那么当你输入12后按回车,程序马上执行每二个静态初始化块,最后才执行把 n的值赋值给常量num,那么最后才调用到System.out.println(T.num);这条语句打印出常量num的值
{
public static void main(String[] args)
{
System.out.println("Test");
System.out.println(new T().num);
}
}class T
{
static
{
System.out.println("之前加载");
}
int n = new Scanner(System.in).nextInt();
final int num = n;
static
{
System.out.println("之后加载");
}
}修改后的运行结果:
Test
之前加载
之后加载
[BLUEJ Input Box]
12
明白了,当主程序执行到需要加载其他的类的时候,该类中加载的顺序是:
1.从上倒下:静态块,静态变量,静态常量(排名不分先后)
2.跳回原程序流程,
3.将静态常量的值以形参的形式拷贝给println(...)方法的实参
4.执行打印,保存在栈中的方法参数被销毁