ClassLoader的定义:

ClassLoader是java中的类加载器,而且不止一种.

      与c/c++不同,Java编写的程序不是可执行文件.exe,而是由许多独立的类文件组成,而且这些类文件不是全部都装入内存,而是根据需要来加载进去.ClassLoader是JVM实现的一部分,ClassLoader包括bootstrap classloader(启动类加载器),在JVM运行的时候加载Java的核心API,其中就包括用户定义的ClassLoader,这是指通过Java程序实现的两个ClassLoader:

       ExtClassLoader,它的作用是用来加载Java扩展的API;

       AppClassLoader,它是用来加载用户机器上CLASSPATH配置目录中的class的.

通常在没有指定ClassLoader的情况下,程序员自定义的类就由AppClassLoader来加载.

ClassLoader加载的流程:

      当运行一个程序,JVM启动,运行bootstrap classloader,该ClassLoader加载Java核心API,然后调用ExtClassLoader来加载扩展API,最后AppClassLoader加载CLASSPATH目录下定义的class.

通过代码来看:

protected synchronized Class loadclass(String name,boolean resolve)
throw ClassNotFoundExciption{
   //首先检查该类name指定的class是否被加载
   Class c = findloadedClass(name);
   if(c == null){
   try{
      if(parent != null){
       //如果parent不为空,则调用loadClass进行加载
       c = parent.loadClass(name,false);
      }else{
       c = findbootstrapClass0(name);
      }
   }catch(ClassNotFoundExciption e){
     e.findClass(name);
   }

 }
  if(resolve){
    resolveClass(c);
   }
   return c;
}

从上面的代码来看,一个类加载的过程使用了一种父类委托模式, 使用这种模式的好处是:

    1. 可以避免重复加载,当父类已经加载了这个类,那么子类就没有必要对其进行加载;

    2. 这样更安全,如果不这样加载,那么随时可以使用自定义的String来动态替代Java核心API中定义的类型,这样会存在非常大的安全隐患,String在启动时就已经被加载,所以,用户自定义类是无法加载自定义的ClassLoader的.

下面来看看方法:

1. loadClass():

     ClassLoader.llaoderClass(String name, boolean resolve)是ClassLoader的入口点.其中的name,是指JVM需要的类的名称,resolve是指告诉方法是否需要解析类.

2. defineClass():

     它接受由原始字节组成的数组,并把它转化为Class对象,原始数组包含从文件系统或网络装入的数据,defineClass管理JVM的许多复杂的实现层面.此方法不能被覆盖,因为它被标记成了final.

3. findSystemClass():

     从本地文件系统装入文件,它在本地文件系统中寻找类文件,,如果存在,就使用defineClass将他转换成为Class对象,将该文件转换成类.

4. resolveClass():

    可以不完全地(不带解析)装入类,也可以完全地(带解析)装入类,这完全取决于resolve这个参数.

5. findLoadedClass():

    findLoadedClass充当一个缓存,当请求loadClass是,调用这个方法来查看ClassLoader是否已装入这个类.这样可以避免重新装入已存在类带来的麻烦.

6. findClass():

    findClass方法包含ClassLoader的所有特殊代码,而无需赋值其他代码;