【问题标题】:Why static initializer block not run in this simple case?为什么在这种简单的情况下静态初始化程序块不运行?
【发布时间】:2013-03-26 09:32:17
【问题描述】:
 class Z
{
    static final int x=10;
    static
    {
        System.out.println("SIB");
    }

}
public class Y
{
    public static void main(String[] args)
    {
        System.out.println(Z.x);
    }
}

输出:10 为什么在这种情况下不加载静态初始化块?当 static x 调用时,z 类的所有静态成员必须至少加载一次,但静态初始化块不加载。

【问题讨论】:

标签: java static load initialization


【解决方案1】:

在声明中带有 static 修饰符的字段被称为 静态字段类变量它们与类相关联, 而不是与任何物体。类的每个实例共享一个 类变量,位于内存中的一个固定位置。 任何对象 可以改变类变量的值,但类变量也可以 在不创建类的实例的情况下进行操作

所以,当你拨打Z.x如下:

System.out.println(Z.x);

它不会初始化类,除非你调用Z.x,它会从那个固定的内存位置得到x

当 JVM 加载 class Z 时运行静态块。这里永远不会加载,因为它可以直接访问 x 而无需加载类。

【讨论】:

    【解决方案2】:

    编译时Z.x值变成10,因为

    static final int x=10; is constant
    

    所以编译器在内联之后创建如下所示的代码

    System.out.println(10); //which is not calling Z class at runtime
    

    【讨论】:

    • +1 这似乎是一个原因。删除 final 关键字会执行静态块。可能是一种编译器优化。
    • @Apurv:这一切都在链接到这个问题的副本中得到了很好的解释(stackoverflow.com/questions/11863800/…
    • 删除 static 或 final 将调用静态初始化块。删除静态意味着我们必须创建将在运行时加载的类 Z 的对象。删除最终意味着值可以更改,而不是恒定值。
    【解决方案3】:

    原因是jvm在加载一个类的时候,把这个类的所有常量成员都放到了常量区,当你需要它们的时候,直接用类名调用就可以了,也就是说,它不需要实例化Z 的类,所以不执行静态初始化块。

    【讨论】:

      【解决方案4】:

      如果 X 不是最终的,在这种情况下,JVM 必须加载类“Z”,然后只会执行静态块。现在 JVM 不需要加载 'Z' 类,因此不会执行静态块。

      【讨论】:

        【解决方案5】:

        它没有运行,因为该类从未加载。

        public class Y
        {
            public static void main(String[] args)
            {
                Z z new Z(); //will load class
                System.out.println(Z.x);
            }
        }
        

        由于Z 上的x 字段已用static final 声明,因此它们是在固定内存位置创建的。访问该字段不需要加载类。

        【讨论】:

          【解决方案6】:

          如果一个常量被声明为static final,它就被称为完美常量。 当编译器编译类 y & 同时编译 sop(Z.x) 时,它将 sop(Z.x) 替换为 sop(10) bcz x 是一个完美的常数,这意味着在字节码类 Y 中不使用 Z 类,所以在运行 Y 类时,Z 类未加载,这就是 Z 类的 SIB 不加载的原因 执行。

          【讨论】:

            猜你喜欢
            • 2011-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-12-07
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多