为什么我的静态代码块不执行?

时间:2013-03-19 20:03:13

标签: java static

我正在尝试运行此代码,但是我发现了最终的静态行为:代码运行时没有执行A的静态块。请提供原因。

class A {
  final static int a=9;
    static { //this block is not executing ??
      System.out.println("static block of A");
     }
}

class Manager {
  static {
    System.out.println("manager sib");
  }

  public static void main(String ...arg) {
    System.out.println("main");
    System.out.println(A.a);
  }
}

为什么A类的静态块不运行?

3 个答案:

答案 0 :(得分:7)

问题在于A.aconstant variable

  

基本类型或类型String的变量,是最终的并使用编译时常量表达式(第15.28节)初始化,称为常量变量。

因此,您的Manager.main方法完全编译,就好像它是:

public static void main(String ...arg) {
    System.out.println("main");
    System.out.println(9);
}

A.a不再有真正的引用,因此A类甚至不需要存在,更不用说初始化了。 (您可以删除A.class并仍然运行Manager。)

如果您依赖于使用A.a来确保初始化类型,则不应添加无操作方法:

public static void ensureClassIsInitialized() {
} 

然后从main方法中调用 。尽管如此,这是非常不寻常的。

答案 1 :(得分:1)

规范http://docs.oracle.com/javase/specs/jls/se7/jls7.pdf 第4.12.1节说,

    一个原始类型或类型String的变量,它是final的并用a初始化    编译时常量表达式(第15.28节),称为常量变量。    变量是否是常量变量可能会产生影响    类初始化(第12.4.1节),二进制兼容性(第13.1节,第13.4.9节)和明确的    任务(§16)。

由于您只访问常量,因此不需要类初始化。

答案 2 :(得分:0)

你可以强制加载你需要的任何课程:

public final class ClassUtils {
  private ClassUtils() {}

  public static void forceLoad(Class<?>... classes) {
    for (Class<?> clazz : classes) {
      try {
        Class.forName(clazz.getName(), true, clazz.getClassLoader());
      } catch (ClassNotFoundException e) {
        throw new AssertionError(clazz.getName(), e);
      }
    }
  }
}

class Manager {
  static {
    ClassUtils.forceLoad(A.class);
// ...
  }

  public static void main(String ...arg) {
// ...
  }
}