链接:验证字节码的安全性和完整性,准备阶段正式为静态域分配存储空间,注意此时只是分配静态成员变量的存储空间,不
包含实例成员变量,如果必要的话,解析这个类创建的对其他类的所有引用。
初始化:类加载最后阶段,若该类具有超类,则对其进行初始化,执行静态初始化器和静态初始化成员变量。
由此可知,我们获取字面常量的Class引用时,触发的应该是加载阶段,因为在这个阶段Class对象已创建完成,获取其引用并
不困难,而无需触发类的最后阶段初始化。下面通过小例子来验证这个过程:
import java.util.*;
class Initable {
//编译期静态常量
static final int staticFinal = 47;
//非编期静态常量
static final int staticFinal2 =
ClassInitialization.rand.nextInt(1000);
static {
System.out.println("Initializing Initable");
}
}
class Initable2 {
//静态成员变量
static int staticNonFinal = 147;
static {
System.out.println("Initializing Initable2");
}
}
class Initable3 {
//静态成员变量
static int staticNonFinal = 74;
static {
System.out.println("Initializing Initable3");
}
}
public class ClassInitialization {
public static Random rand = new Random(47);
public static void main(String[] args) throws Exception
{
//字面常量获取方式获取Class对象
Class initable = Initable.class;
System.out.println("After creating Initable ref");
//不触发类初始化
System.out.println(Initable.staticFinal);
//会触发类初始化
System.out.println(Initable.staticFinal2);
//会触发类初始化
System.out.println(Initable2.staticNonFinal);
//forName方法获取Class对象
Class initable3 = Class.forName("Initable3");
System.out.println("After creating Initable3 ref");
System.out.println(Initable3.staticNonFinal);
}
}
执行结果: