java中的类和接口初始化

时间:2015-08-18 04:51:01

标签: java

以下是代码,

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之后&链接,在初始化阶段,变量jfinal首先使用1进行初始化。变量k也使用1初始化。

但输出为变量0提供了k

我如何理解这一点?

注意:编译器实际上会替换前向引用规则引用的变量j的值,而不像k

3 个答案:

答案 0 :(得分:6)

static final int会使j成为编译时常量。因此,它的值将作为字节代码本身的一部分出现并传递。因此,当您的类被初始化时,j将为1 。但是k只是static int,因此自静态初始化程序以来将打印其默认值在初始化k的值之前运行。

答案 1 :(得分:5)

您在初始化之前尝试访问k,这就是为什么它是0.(h在定义peekk()之前初始化为k,因此{ {1}}返回0,因为字段是从上到下初始化的。)peekk()是最终的,所以它先执行;在声明j之前,i获得i或1的值。

Here's相应的Oracle文档:

  

接下来,按文本顺序执行类的类变量初始值设定项和静态初始值设定项,或接口的字段初始值设定项,就像它们是单个块一样。

答案 2 :(得分:3)

" 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;