java类加载机制简要分析

来源:互联网 发布:太平洋证券炒股软件 编辑:程序博客网 时间:2024/06/05 06:42

 

系统默认的类加载器运行流程:

    首先,系统初始化一个系统默认的类加载器 (以上三者之一,通常是AppClassLoader)实例,然后调用该实例的ClassLoader.loadClass(String name)方法加载

采用委托机制,自上而下的搜索class文件,直到找到相应的类。类加载器本身也是类(除了BootStrap,他不是java类,在虚拟机启动时由系统创建的,他是用C++写的二进制代码)。当java虚拟机要加载一个类时,首先用当前线程的类加载器去加载线程的第一个类。如果A类中引用了B类,java虚拟机将使用A类的类加载器去加载B。用户还可以直接调用ClassLoader.loadClass()方法来指定某个类加载器去加载某个类。

创建自己的类加载器:

defineClass 方法将一个 byte 数组转换为 Class 类的实例。这种新定义的类的实例可以使用 Class.newInstance 来创建。 

网络类加载器子类必须定义方法 findClass 和 loadClassData,以实现从网络加载类。下载组成该类的字节后,它应该使用方法 defineClass 来创建类实例。示例实现如下:

     class NetworkClassLoader extends ClassLoader {

         String host;

         int port;

         public Class findClass(String name) {

             byte[] b = loadClassData(name);//.class文件中的字节码转化成字节数组,储存在b[]

             return defineClass(name, b, 0, b.length);//将字节数组转化成Class类的实例返回

         }

         private byte[] loadClassData(String name) {

             // load the class data from the connection

              . . .

         }

     }

Protected Class<?> loadClass(String name,boolean resolve)throws ClassNotFoundException

使用指定的二进制名称来加载类。此方法的默认实现将按以下顺序搜索类: 

1.调用 findLoadedClass(String) 来检查是否已经加载类。

2.在父类加载器上调用 loadClass 方法。如果父类加载器为 null,则使用虚拟机的内置类加载器。

3.调用 findClass(String) 方法查找类。

鼓励用 ClassLoader 的子类重写 findClass(String),而不是使用此方法。

protected Class<?> findClass(String name) throws ClassNotFoundException

使用指定的二进制名称查找类。此方法应该被类加载器的实现重写,该实现按照委托模型来加载类。在通过父类加载器检查所请求的类后,此方法将被 loadClass 方法调用。默认实现抛出一个 ClassNotFoundException

原创粉丝点击