据说java中的静态块只在加载该类时运行一次。但它究竟意味着什么?此时是由JVM(Java虚拟机)加载的类?
是否在调用该类中的main方法时?并且当main方法开始执行时,是否还加载了同一类的所有超类?
考虑A扩展B和B扩展C.所有都有静态块。如果A有main方法,那么静态块的执行顺序是什么?
答案 0 :(得分:10)
这在JLS的Execution部分中有所描述。即:
类的初始化包括执行其静态初始化程序和类中声明的静态字段的初始化程序。接口的初始化包括为接口中声明的字段执行初始值设定项 在初始化类之前,必须初始化其直接超类,但不需要初始化类实现的接口。同样,在初始化接口之前,不需要初始化接口的超接口。
所以在你的例子中,"最顶层的静态块" class(C
)首先运行,然后运行B
,然后是派生最多的类。
有关加载课程的所有步骤的详细说明,请参阅该文档。
(第一次使用时会加载类。)
答案 1 :(得分:2)
我认为以下示例将解决您的所有问题:
在初始化类之前,如果以前没有初始化它们,则会初始化它的超类。
因此,测试程序:
class Super {
static { System.out.print("Super "); }
}
class One {
static { System.out.print("One "); }
}
class Two extends Super {
static { System.out.print("Two "); }
}
class Test {
public static void main(String[] args) {
One o = null;
Two t = new Two();
System.out.println((Object)o == (Object)t);
}
}
打印:
Super Two false
第一类永远不会被初始化,因为它没有被积极使用,因此永远不会被链接。仅在初始化超类Super之后才初始化类Two。
有关详细信息,请访问此link
编辑详细信息:删除了令人困惑的行。
答案 2 :(得分:1)
来自Java Language Specification:
中详细介绍了该流程类的初始化包括执行其静态初始化程序和类中声明的静态字段(类变量)的初始化程序。接口的初始化包括为在那里声明的字段(常量)执行初始化器。
在初始化类之前,必须初始化其超类,但不会初始化类实现的接口。同样,在初始化接口之前,不会初始化接口的超接口。