资源描述:
《Java类加载机制初探》由会员上传分享,免费在线阅读,更多相关内容在教育资源-天天文库。
1、类加载机制初探记得在刚学JAVA的时候,类的加载机制和初始化顺序经常被弄的糊里糊涂,其实当我们不太了解某些事情的时候,不防去做一做实验,让代码的运行结果说话,这或许能帮助我们更好地了解一些事情.今天我们就用一些代码来看一下类是如何被加载的,并且当有继承关系的时候,类的加载顺序又是怎么样的.先看代码吧/* * Test4.java * * Created on 2007-9-21, 9:33:31 * * To change this template, choose Tools
2、 Templates * and open the template in the editor. */pa
3、ckage test1;/** * * @author hadeslee */public class Test4 { private void testClassForName(String name) throws ClassNotFoundException{ Class c=Class.forName(name); } private void testNewInstance(String name) throws ClassNotFoundException, InstantiationException, IllegalAccessExceptio
4、n{ Class c=Class.forName(name); Object obj=c.newInstance(); System.out.println(obj); } public static void main(String[] args)throws Exception { Test4 t=new Test4(); t.testClassForName("test1.B"); new B(); new B(); }}class A{ private int a
5、j; { aj=20; System.out.println("A成员初始化块"); } private static int ai; static { ai=10; System.out.println("A静态初始化块"); } public A(){ System.out.println("A构造函数"); }}class B extends A{ private static int bi; static { bi=30; Syste
6、m.out.println("B静态初始化块"); } private int bj; { bj=40; System.out.println("B成员初始化块"); } public B(){ System.out.println("B构造函数"); }}在代码里面我们总共有三个类,一个是做测试用的Test4,一个是A,一个是A的子类B,我们在A和B类里面都有很多输出,一个是静态初始化的输出,一个是成员初始化的输出,一个是在构造函数里面的输出,从这些输出我们可以知道代码的执行顺序,以上代码运行输出如下:A静态初
7、始化块B静态初始化块A成员初始化块A构造函数B成员初始化块B构造函数A成员初始化块A构造函数B成员初始化块B构造函数从上面我们可以看出,A和B的静态初始化块只被执行了一次,也就是类的对象将要被生成的时候,它会执行,并且执行的顺序如下:父类的静态成员,子类的静态成员,父类的成员变量和构造方法,子类的成员变量和构造方法.当再用这个类生成对象的时候,静态的部份就不再被调用了.因为静态是类的所有实例所共享的,所以它在整个虚拟机的生命周期内只执行一次.如果我们加上一个t.testClassForName("test1.B");放在main函数的最后面,我们会发现输出还是和刚刚一样,没有任何改变,这个时
8、候,我们知道,当我们调用Class.forName(name);的时候,类是不会自动初始化的,它默认只是把这个类的字节码读入内存,但是并没有初始化这个类.只有我们调用了newInstance()的时候,它才会被初始化.在这里我们再这样试一下:把A和B生成的class文件去掉,然后再分别调用Class.forName和newB(),看看会怎么样,我们会发现当我们调用Class.forName的时候,当我们要fo