“当一个class级加载”实际意味着什么?
据说java中的静态块只在加载该类时运行一次。 但它究竟意味着什么? 在哪一点上是由JVM(Java虚拟机)加载的类?
是否在调用该类中的main方法时? 并且当main方法开始执行时,是否还加载了同一类的所有超类?
考虑A扩展B和B扩展C.所有都有静态块。 如果A有main方法,那么静态块的执行顺序是什么?
这在JLS的执行部分中描述。 即:
类的初始化包括执行其静态初始化程序和类中声明的静态字段的初始化程序。 接口的初始化包括为接口中声明的字段执行初始值设定项。
在初始化类之前,必须初始化其直接超类 ,但不需要初始化类实现的接口。 同样,在初始化接口之前,不需要初始化接口的超接口。
所以在你的例子中,“topmost”类( C
)的静态块首先运行,然后运行B
运行,然后运行最多的类。
有关加载类的所有步骤的详细说明,请参阅该文档。
(类在首次使用时会被加载。)
我认为以下示例将解决您的所有问题:
在初始化类之前,如果先前未初始化类,则初始化其超类。
因此,测试程序:
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。
有关详细信息,请访问此链接
编辑详细信息:删除了令人困惑的行。
从Java语言规范 :
类的初始化包括执行其静态初始化程序和类中声明的静态字段(类变量)的初始化程序。 接口的初始化包括为在那里声明的字段(常量)执行初始化器。
在初始化类之前,必须初始化其超类,但不会初始化类实现的接口。 同样,在初始化接口之前,不会初始化接口的超接口。
Java虚拟机规范中更详细地描述了该过程。