java中的类加载器大致可以分为两类,一类是系统提供的,另外一类则是由 Java 应用开发人员编写的。系统提供的类加载器主要有下面三个:

引导类加载器(bootstrap class loader):它用来加载 Java 的核心库,是用原生代码来实现的,并不继承自 java.lang.ClassLoader。

扩展类加载器(extensions class loader):它用来加载 Java 的扩展库。Java 虚拟机的实现会提供一个扩展库目录。该类加载器在此目录里面查找并加载 Java 类。

系统类加载器(system class loader):它根据 Java 应用的类路径(CLASSPATH)来加载 Java 类。一般来说,Java 应用的类都是由它来完成加载的。可以通过 ClassLoader.getSystemClassLoader() 来获取它。

classloader 加载类用的是全盘负责、委托机制。所谓全盘负责,即是当一个classloader加载一个Class的时候,这个Class所依赖的和引用的所有 Class也由这个classloader负责载入,除非是显式的使用另外一个classloader载入;委托机制则是先让parent(父)类加载器 (而不是super,它与parent classloader类不是继承关系)寻找,只有在parent找不到的时候才从自己的类路径中去寻找。此外类加载还采用了cache机制,也就是如果 cache中保存了这个Class就直接返回它,如果没有才从文件中读取和转换成Class,并存入cache。

每个ClassLoader加载Class的过程是:

1. 检测此Class是否载入过(即在cache中是否有此Class),如果有到8,如果没有到2

2. 如果parent classloader不存在(没有parent,那parent一定是bootstrap classloader了),到4

3. 请求parent classloader载入,如果成功到8,不成功到5

4. 请求jvm从bootstrap classloader中载入,如果成功到8

5. 寻找Class文件(从与此classloader相关的类路径中寻找)。如果找不到则到7.

6. 从文件中载入Class,到8.

7. 抛出ClassNotFoundException.

8. 返回Class.

其中5.6步我们可以通过覆盖ClassLoader的findClass方法来实现自己的载入策略。甚至覆盖loadClass方法来实现自己的载入过程。