【问题标题】:static and final static assignment静态和最终静态分配
【发布时间】:2015-08-02 14:15:18
【问题描述】:

我用的是同一种概念,我在头等舱里用过。
b 被初始化为 0,我在使用 b 的所有地方都得到了 0。 过了一段时间,我得到了原因并运行了调试器,发现在函数调用之前 a 没有被分配任何值。变量 a 的值只有默认值 0。

但是当我运行 Test2 类时。它给出了输出 5。

我想知道这个初始化是什么时候发生的? 我知道静态变量在编译时获得价值。但是静态决赛呢? 这个变量什么时候得到它的值?

public class Test1 {

    static int b=add();
    static int add()
    {
        return a;
    }
    static int a=5;

    public static void main(String[] args) {        
        System.out.println(b);
    }
}
//Gives output 0


public class Test2 {

    static int b=add();
    static int add()
    {
        return a;
    }
    final static int a=5;

    public static void main(String[] args) {    
        System.out.println(b);
    }
}

//gives output 5

【问题讨论】:

  • a 尚未在 Test 1 中分配,如果您将 static int a=5; 移动到第一行,您将得到 5。正如您在测试 2 值将被设置

标签: java variables static variable-assignment final


【解决方案1】:

来自Java语言规范的12.4.2部分,初始化Class的过程如下:

  • 然后,初始化最终类变量和接口字段,其值为编译时常量表达式(§8.3.2.1、§9.3.1、 §13.4.9、§15.28)。
  • 接下来,执行类的类变量初始化程序和静态初始化程序,或者类的字段初始化程序 界面,按文本顺序排列,就好像它们是一个单独的块一样。

所以最终变量将在静态变量之前初始化。你会得到输出5。

【讨论】:

    【解决方案2】:

    原始类型和String 类型的final static 字段由Java 编译器专门处理:它们是编译时常量。它们的值只是内联到它使用的代码中。我们来看看生成的字节码。

    Test1类:

    static int add();
    Code:
       0: getstatic     #17                 // Field a:I
       3: ireturn
    

    所以它确实加载了一个静态字段。

    Test2类:

    static int add();
    Code:
       0: iconst_5
       1: ireturn
    

    这里它只是推送一个预定义的常量值5,甚至没有引用常量字段。

    【讨论】:

      【解决方案3】:

      只是为了补充其他答案:

      在a 不是final 的第一种情况下,b 的值在a 之前分配,这就是您得到0 的原因。分配的顺序由语句的顺序决定。如果你将static int a=5; 移动到b 的赋值语句之前,你将得到5。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-04
        • 2019-11-13
        • 1970-01-01
        相关资源
        最近更新 更多