Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
java中的类和接口初始化_Java - Fatal编程技术网

java中的类和接口初始化

java中的类和接口初始化,java,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 ClassAndInterfac

下面是代码

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
加载并链接
类Z
后,在初始化阶段,变量
j
作为
final
首先用
1
初始化。变量
k
也用
1
初始化

但是对于变量
k
,输出给出
0

我如何理解这一点


注意:编译器实际上会替换变量
j
的值,只要它是按照正向引用规则引用的,这与
k
不同,您试图在初始化变量
k
之前访问它,这就是为什么它是0。(
h
在定义
k
之前被初始化为
peekk()
,因此
peekk()
返回0,因为字段是从上到下初始化的。)
j
是最终的,所以首先执行;在声明
i
之前,因此
i
获取
j
或1的值

适当的Oracle文档:

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


static final int
将使
j
成为编译时常量。因此,它的值将作为字节码本身的一部分呈现和传递。因此,初始化类时,
j
将为1。但是
k
只是
static int
,因此它的默认值将被打印出来,因为静态初始值设定项在
k
值初始化之前运行。

在编译代码时,“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;

同样的情况也发生在
j
上。但由于编译时替换(如LostMind的回答中所述),它给出了正确的结果。@TimBiegeleisen我做到了。还有一个问题:
System.out.println(Z.peek())输出1,其中as
System.out.println(Z.h)输出0。怎么做?当你说“在初始化之前尝试访问k,这就是为什么它是0”时,你是说,在初始化阶段之前有一个单独的阶段,
k
被设置为0?是的,那个阶段是什么?基本上。Java将在所有其他代码运行之前(在编译时,IIRC)为所有代码提供默认值输出1,其中as
System.out.println(Z.h)输出0。如何?@overexchange Yes所有出现的“J”都被实际数字1替换。请看下面我的答案。还有一个问题:
System.out.println(Z.peek())输出1,其中as
System.out.println(Z.h)输出0。如何?一旦调用了
System.out.println(Z.peek())
,所有变量都被正确初始化(为1)。在main方法中:
System.out.println(Z.i);System.out.println(Z.peek());系统输出打印ln(Z.h)。输出:主方法中的1 1 0:
System.out.println(Z.peek());系统输出打印ln(Z.h)。产出:10。产量没有变化。注意:即使我更改了SOP的顺序,行为也一样。@NamanGala-这是因为当
h
被初始化时,k是
0
。但是
peek()
在调用方法时返回
k
的当前值。您正在初始化类后调用方法。所以,值是1。明白了吗?一个补充,不同原始数据类型的默认值是什么?@overexchange单击此处并向下滚动查看表格