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 为什么静态初始化块在这种情况下不加载?当静态x调用时,所有类z的静态成员必须至少加载一次但静态初始化块不加载。
答案 0 :(得分:1)
编译时Z.x值变为10,因为
static final int x=10; is constant
所以编译器在内联
之后创建如下所示的代码System.out.println(10); //which is not calling Z class at runtime
答案 1 :(得分:1)
调用在其声明中具有static修饰符的字段 静态字段或类变量。 他们与班级有关, 而不是与任何对象。该类的每个实例都共享一个 类变量,位于内存中的一个固定位置。任何对象 可以更改类变量的值,但类变量也可以 在不创建类的实例的情况下进行操作
因此,当您拨打Z.x
时如下:
System.out.println(Z.x);
它不会初始化该类,除非您调用Z.x
它将从该固定内存位置获取x
。
当JVM加载class Z
时,将运行静态块。这里永远不会加载,因为它可以直接访问x
而不加载类。
答案 2 :(得分:1)
原因是当jvm加载一个类时,它将所有类的常量成员放入常量区域,当你需要它们时,只需要通过类名直接调用它们,也就是说,它不需要实例化Z的类。所以不执行静态初始化块。
答案 3 :(得分:0)
它不会运行,因为该类永远不会被加载。
public class Y
{
public static void main(String[] args)
{
Z z new Z(); //will load class
System.out.println(Z.x);
}
}
由于x
上的Z
字段已声明为static final
,因此它们是在固定内存位置创建的。访问此字段不需要加载类。
答案 4 :(得分:0)
如果X不是最终的,那么JVM必须加载类'Z',然后才会执行静态块。现在JVM不需要加载'Z'类,因此不会执行静态块。
答案 5 :(得分:0)
如果将常量声明为静态最终值,则将其称为完全常量。 当编译器编译类y&在编译sop(Z.x)时,它将sop(Z.x)替换为 sop(10)bcz x是一个完美的常量,它意味着在字节码中不使用Y类 类Z因此在运行类Y类Z时不加载这就是为什么Z类的SIB不是 执行。