实例如下:
public class LoadingTest {
public static LoadingTest obj=new LoadingTest();
public static int value1;
public static int value2=0;
public LoadingTest()
{
value1=10;
value2=value1;
System.out.println("初始化 value1 之前-->"+value1);
System.out.println("初始化 value2 之前-->"+value2);
}
public static void main(String args[])
{
System.out.println("初始化 value1 之后-->"+value1);
System.out.println("初始化 value2 之后-->"+value2);
}
}
结果:
初始化 value1 之前-->10 初始化 value2 之前-->10 初始化 value1 之后-->10 初始化 value2 之后-->0
分析:
类的加载流程:加载字节码、验证阶段、准备阶段、解析阶段、初始化阶段 * 在准备阶段:jvm会对存放在方法区中的类数据信息的类变量执行初始化 * 这里的初始化只是对类中的所有静态变量分配内存空间,并为其设置初始值 * 初始化阶段:jvm会将一个类中所有的static关键字标示的代码统统执行一遍 * 回到程序,为什么结果是这样呢? * 因为:首先在准备阶段,jvm会按照顺序准备obj、value1、value2 * 也就是开辟空间并设置初始值,此时obj=null,value1=value2=0;然后,到了初始化阶段,会一次检查 * obj、value1、value2是否需要初始化,obj通过构造方法初始化, * 此时value1、value2的初始值被覆盖为10,然后到value1,用户没有直接赋值 * 不用覆盖,最后到了value2,用户赋值0,那么就会覆盖之前的值,因此value2又回到0 接下里我们变换代码的顺序:其它不变,执行的结果是:public static int value1; public static int value2=0; public static LoadingTest2 obj=new LoadingTest2();
加载的过程还是和上面解释的一样,只是因为代码的顺序发生变化结果就不同。初始化 value1 之前-->10 初始化 value2 之前-->10 初始化 value1 之后-->10 初始化 value2 之后-->10
总结:类加载的结果和代码的顺序有关。