下面代码执行后最终的结果是:
public class StaticDemoSupper { static { System.out.println("A"); } /** * */ public StaticDemoSupper() { System.out.println("B"); } } public class StaticDemoChild extends StaticDemoSupper { static{ System.out.println("C"); } /** * */ public StaticDemoChild() { System.out.println("D"); } public static void main(String[] args) { new StaticDemoChild(); } }
A C B D
执行顺序是:父类的静态代码块,子类的静态代码块 父类的构造方法,子类的构造方法
(1) 遇 到new、getstatic、putstatic或invokestatic这4条字节码指令时,如果类没有进行过初始化,则需要先触发其初始化。生成 这4条指令的最常见的Java代码场景是:使用new关键字实例化对象的时候,读取或设置一个类的静态字段(被final修饰、已在编译期把结果放入常量 池的静态字段除外)的时候,以及调用一个类的静态方法的时候。
(2) 使用java.lang.reflect包的方法对类进行反射调用的时候,如果类没有进行过初始化,则需要先触发其初始化。
(3) 当初始化一个类的时候,如果发现其父类还没有进行过初始化,则需要先触发其父类的初始化。
(4)当虚拟机启动时,用户需要指定一个要执行的主类(包含main()方法的那个类),虚拟机会先初始化这个主类。
只有上述四种情况会触发初始化,也称为对一个类进行主动引用,除此以外,所有其他方式都不会触发初始化,称为被动引用
静态代码块中会在编译阶段初始化到类的常量池中