之前整理了《JVM之类加载机制》的文章,对于一个类的初始化阶段介绍太过简略,这里再开一篇文章,着重介绍类的初始化流程。
类初始化是类加载过程的最后一个阶段,到初始化阶段,才真正开始执行类中的Java程序代码。虚拟机规范严格规定了有且只有四种情况必须立即对类进行初始化:
遇到new、getstatic、putstatic、invokestatic这四条字节码指令时,如果类还没有进行过初始化,则需要先触发其初始化。生成这四条指令最常见的Java代码场景是:使用new关键字实例化对象时、读取或设置一个类的静态字段(static)时(被static修饰又被final修饰的,已在编译期把结果放入常量池的静态字段除外)、以及调用一个类的静态方法时。
使用Java.lang.refect包的方法对类进行反射调用时,如果类还没有进行过初始化,则需要先触发其初始化。
当初始化一个类的时候,如果发现其父类还没有进行初始化,则需要先触发其父类的初始化。
当虚拟机启动时,用户需要指定一个要执行的主类,虚拟机会先执行该主类,也就是main方法所在的类。
上面所说时显示的对象创建,还有几种隐式初始化的方式也说明一下:
给String类型变量赋值时,若String对象在常量池中不存在,则创建一个新的String对象
对String对象进行拼接操作,同上
自动装箱机制可能会引起一个原子类型的包装类对象被创建。
这里再说一下类不被初始化的情况:
对于静态字段(没有final修饰),只有直接定义这个字段的类才会被初始化,子类调用父类的静态字段并不会触发子类的初始化
static