首页 > 代码库 > JAVA类的加载过程

JAVA类的加载过程

周末闲来无事,做个小例子去看一下JAVA代码初始化的过程

 

JAVA代码初始化分为两个步骤:类初始化,对象初始化。

类初始化

1 类初始化是指类加载器将类加载到内存时,对类成员的初始化过程(其中包括static修饰的变量)。

2 对于加载完的类,它的类变量都会赋一个默认值,即使你定义时就赋值了。

3 例如int类型就是0,引用类型就是null。

 

对象初始化

 

1 其实和类初始化差不多,但是他通过构造函数对对象进行了赋值

 

其实简单来说

类初始化做了2件事情:1 把所有属性全部赋值为0或者NULL,2 然后给静态变量进行赋值

对象初始化做了1件事情:1 执行构造函数给普通变量赋值或者静态变量赋值(每次NEW 对象时是不执行静态代码块的)

**需要注意的是执行顺序,构造函数会先执行,静态代码块后执行。

                

 

例子1 初始化

public class JvmTest {    private  JvmTest JvmTest ;//private JvmTest jvmTest=null    private  int count1;      //private int count1=0;    private  static int count2;//private int static=0;    public static void main(String[] args) {        System.out.println("count1=" + new JvmTest().count1);        System.out.println("count2=" + new JvmTest().count2);        System.out.println("JvmTest=" + new JvmTest().JvmTest);    }}

 执行结果

count1=0count2=0JvmTest=null

 

------------------------------------------------------------------------------------------------------------------------------------

 

例子2 初始化+赋值的过程

如下这样的代码

public class JvmTest {    private static JvmTest JvmTest= new JvmTest();    private int count1=5;    private static int count2=5;    }

 

可以理解为

public class JvmTest {    private static JvmTest JvmTest;    private int count1;    private static int count2;    static{        System.out.println("static init---------------");        count2=5;        JvmTest=new JvmTest();    }    JvmTest(){        System.out.println("constrctor init---------------");        count1=5;    }    public static void main(String[] args) {        System.out.println("count1=" + JvmTest.count1);        System.out.println("count2=" + JvmTest.count2);        System.out.println("JvmTest=" + JvmTest.JvmTest);    }}

 

 执行结果

static init---------------constrctor init---------------count1=5count2=5JvmTest=test.test.JvmTest@15db9742

 

初始化的过程会将定义的属性先赋值为0或者NULL,然后再在构造函数和静态代码区中进行正式的赋值

例3 初始化 static和constructor的初始化顺序为,先执行构造函数块,再执行static。

public class JvmTest {    private static JvmTest JvmTest = new JvmTest();    private int count1 =5;    private static int count2= 5;    static{        System.out.println("static init");        count2++;        System.out.println(count2);    }    JvmTest(){        System.out.println("constructor init");        count1++;        count2++;        System.out.println(count1);        System.out.println(count2);    }    public static void main(String[] args) {        System.out.println("类初始化完成");    }}

 

 执行结果(第一步是类初始化属性为0或者为NULL),第二步对象初始化在构造函数和静态代码区中进行赋值

constructor init//执行了 count=5;count1++;count2++61static init//执行了count2=5;count2++6类初始化完成

 

 最后一道思考题

 

package test.test;import org.junit.Test;public class JvmTest {    private static JvmTest JvmTest = new JvmTest();    private int count1 = 5;    private static int count2 = 5;    static {        System.out.println("static init");        count2++;    }    JvmTest() {        System.out.println("constructor init");        count1++;        count2++;    }    public static void main(String[] args) {        System.out.println("count1=" + new JvmTest().count1);        System.out.println("count2=" + new JvmTest().count2);        System.out.println("JvmTest=" + new JvmTest().JvmTest);    }}

 

 

 

 

constructor initstatic initconstructor initcount1=6constructor initcount2=8constructor initJvmTest=test.test.JvmTest@15db9742

 

大致步骤为

第一步类初始化后静态count2的值为6。其他的无视

第二步 new JvmTest时会允许构造函数,每次都会执行count1=5;count1++;count2++; 而不会执行static了。

答案

count2是静态变量,打印输出count2是在第二次NEW的时候输出的,所以是初始化的6和2次++的过程,答案为8

count是类的属性,所以每次都是count=5,count++,答案为6

 

最后的总结

1 JAVA代码初始化的过程是给属性初始化0或者NULL

2 执行构造函数为普通属性赋值

3 执行静态代码区,为静态变量赋值

 综上所述,初始化一个JAVA类代码会包含执行3个过程---》属性初始化+通过执行构造函数为普通变量赋值+通过执行静态代码区为静态变量赋值

如果我们NEW一个对象的过程呢?

1 初始化普通属性(非static变量)

2 执行构造函数为普通或者静态属性赋值

从这里看出,NEW的过程不会在允许static的代码块了,只会允许构造函数。