java中静态变量的初始化

java中静态变量的初始化,java,static,Java,Static,我在一次采访中被问到这个问题 如果你这样做 private int c = d; private int d; 它会导致编译时错误 在定义字段之前无法引用该字段。 说到面试问题 1 public static int a = initializeStaticValue(); 2 public static int b = 20; 3 public static int initializeStaticValue() { 4 retu

我在一次采访中被问到这个问题

如果你这样做

    private int c = d;
    private int d;
它会导致编译时错误

在定义字段之前无法引用该字段。

说到面试问题

    1  public static int a = initializeStaticValue();
    2  public static int b = 20;


    3  public static int initializeStaticValue() {
    4   return b;

       }

    5   public static void main(String[] args) {
           System.out.println(a);
           System.out.println(b);
        }
我给出了与
a
通过调用initializeStaticValue()初始化相同的响应,其中引用了未定义的
b

但是程序运行良好,可以编译并打印

0
20
我不明白为什么

Cannot reference a field before it is defined. 
没有扔

其次,当我调试它时,为什么控件会在

3  public static int initializeStaticValue() {

我的意思是,为什么这是程序的起始位置。

如果您关心初始化/执行的顺序,下面是将要发生的事情(我认为这不是很准确,只是给您一个想法):

  • JVM被要求运行Java应用程序(假设您的类被命名)
    Foo
    ,它尝试从类路径加载
    Foo
  • 加载
    Foo
    ,并为静态变量分配默认值(0表示int)
  • 将执行静态初始化器,首先在第1行运行该初始化器,该初始化器依次调用
    initializeStaticValue()
    ,此时返回
    b
    的值(0),并将其分配给
    a
  • 静态初始化继续,并进入第2行。它为
    b
    分配20
  • Foo
    已成功加载和初始化,JVM调用
    Foo.main()

  • 你的问题不是很清楚:1
    b
    initializeStaticValue()
    之前定义,因此
    的任何错误都不能在定义字段之前引用该字段。2.在运行
    main()
    之前,您的类需要首先由JVM加载,您可以将静态字段初始化视为加载过程的一部分,这就是为什么
    initializeStaticValue()
    main()
    之前启动。这就是你想要的吗?@Adrian:一旦控件到达第1行(上面标记),就会调用initializeStaticValue()。编译程序是如何知道此时存在b的?@ShirgillAnsari在类加载后立即返回静态变量
    b
    “exists”。但是,尚未为其赋值(因此它具有默认值,这就是initializeStaticValue返回0的原因)。前一种情况是语义语言限制,因为它从来没有意义(这种行为与局部变量类似,例如):但是编译器/语言不研究方法,因为这些情况在编译时很快变得不确定(请参阅)。它与:
    initializeStaticValue()类似
    是在
    a
    之后声明的,为什么编译器在第1行时知道它存在?@user2864740:我同意静态变量b在类加载后立即“存在”,并且它拥有默认值0。但是如果调试程序,您会注意到调试器将自身置于initializeStaticValue()-->public static int a=initializeStaticValue();-->公共静态int b=20。为什么在public static int a=initializeStaticValue()之前调用initializeStaticValue?@AdrianShum,不建议请求接受,这会给提问者带来压力。回答得好。@AdrianShum,完全同意你的观点。我们所有人都在接受未被接受的投票结果。我不太确定什么协议可以让新用户熟悉accept功能。希望他们在提问之前先浏览一下网站的介绍。@BruceWayne让我们在meta stack overflow中提出这个问题:)@Adrian:我知道accept函数。再一次谢谢你。@AdrianShum,我几乎可以肯定这个问题一定是以前提过的。我会试着找的,如果你先找到的话请告诉我。