下面是代码,
class Z{
static int peekj(){
return j;
}
static int peekk(){
return k;
}
static int i = peekj();
static int h = peekk();
static final int j = 1;
static int k = 1;
}
public class ClassAndInterfaceInitialization {
public static void main(String[] args) {
System.out.println(Z.i);
System.out.println(Z.h);
}
}
在遵循静态初始化的前向引用规则之后,我看到输出如下:
1
0
class Z
加载后&在初始化阶段,变量j
是final
,首先用1
初始化。变量k
也用1
初始化。
但是输出给变量k
的是0
我怎么理解这个?
注意:与k
j
的值。 static final int
将使j
成为编译时常数。因此,它的值将作为字节码本身的一部分呈现和传递。因此,当您的类被初始化时,j
将为1。但是k
只是static int
,所以它的默认值将被打印,因为你的静态初始化器在k
的值初始化之前运行。
您试图在初始化之前访问k
,这就是为什么它为0。(h
在k
被定义之前被初始化为peekk()
,所以peekk()
返回0,因为字段是从上到下初始化的。)j
是final,所以首先执行;在i
声明之前,因此i
获得j
的值或1。
下面是相应的Oracle文档:
接下来,按文本顺序执行类变量初始化器和类的静态初始化器,或者接口的字段初始化器,就像它们是单个块一样。
"j"是一个常量,所以当代码被编译时,j在整个程序中被数字1取代。如果你是外星人,你可以读字节码代码会是这样的
static int peekj(){
return 1;// j is replaced by the Actual Number 1
}
"静态变量在类加载时初始化"所以当类加载时,下列语句按顺序执行
static int i = peekj(); // Executed First, as peekJ() directly returns 1 so i is equal to 1
static int h = peekk(); // Executed Second, Now peekk() returns "THE VALUE OF k" which is not set yet i.e default value of int is given 0(zero)
//So h is equal to 0
static final int j = 1; // This statement doesn't exist as all j's are replaced with actual Number 1 when we compiled java to .class
static int k = 1; // Executed last, So now the value of 'k' is being set, after the value of 'h' has already been set to zero
注意:这样做是为了得到输出1和1,即i =1和h =1;因为k的值首先被设置为1。
static int k = 1;
static int i = peekj();
static int h = peekk();
static final int j = 1;