我有这段代码,我正在使用-verbose:class选项运行它,以查看已加载的类。令我惊讶的是,它显示它已加载类A1和A2,但未调用静态块。
有人可以解释这种行为吗
package P1;
import java.lang.reflect.InvocationTargetException;
public class DemoReflection {
static {
System.out.println("Loading Demo");
}
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException,
InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
System.out.println("A2 " + A2.class.getClassLoader().getClass());
System.out.println("Demo " + DemoReflection.class.getClassLoader().getClass());
System.out.println("A1 " + A1.class.getClassLoader().getClass());
}
}
class A1 {
static {
System.out.println("Loading A1");
}
}
class A2 extends A1 {
static {
System.out.println("Loading A2");
}
public A2() {
System.out.println("m2");
}
public void m1() {
System.out.println("m1");
}
}
class A3 {
static int a3Id = 3;
static {
System.out.println("Loading A3");
}
}
答案 0 :(得分:3)
JLS §8.7说:
在初始化类时,将执行在类中声明的静态初始化程序(第12.4.2节)。
那么初始化是什么意思?让我们参考JLS §12.4.2。这描述了详细的初始化过程。但是,这里的点JLS §12.4.1可能更合适。它说:
类或接口类型T将在以下任何一种首次出现之前立即初始化:T是一个类,并创建T的实例。 T是一个类,并调用T声明的静态方法。 分配了由T声明的静态字段。 使用T声明的静态字段,并且该字段不是常量变量(第4.12.4节)。 T是顶级类(第7.6节),并执行一个词法嵌套在T(第8.1.3节)中的assert语句(第14.10节)。
这些选项都不适合您的情况,因此不会调用静态块。
答案 1 :(得分:0)
简单版本: 静态块仅在您第一次创建对象或访问该类的静态成员时运行。