Java虚拟机(JVM)中的类加载器(ClassLoader)负责加载.class文件到JVM中,使其成为可用的类。JVM提供了几种内置的类加载器,它们按照层次结构组织,如下所述:
1. **根类加载器(Bootstrap ClassLoader)**:
- 也称为启动类加载器,是所有类加载器的父加载器。
- 它负责加载Java核心库类(如java.lang.Object),这些类通常以rt.jar的形式存在于JDK的jrlib目录下。
- 根类加载器是用C++编写的,不是通过Java代码实现的。
2. **扩展类加载器(Extension ClassLoader)**:
- 继承自根类加载器,用于加载Java的扩展目录中的类库。
- 默认情况下,它会加载JAVA_HOME/lib/ext或者系统属性`java.ext.dirs`指定的目录下的类库。
3. **应用程序类加载器(Application ClassLoader)**:
- 也称为系统类加载器,继承自扩展类加载器。
- 它负责加载应用程序的类路径(classpath)上指定的类库。
- 通常,它是通过`ClassLoader.getSystemClassLoader()`方法获得的。
4. **自定义类加载器(User-Defined ClassLoader)**:
- 继承自java.lang.ClassLoader类的子类,由用户自定义的类加载器。
- 允许开发者控制类的加载过程,用于实现类加载的不同策略,如热部署、网络加载等。
类加载器之间的父子关系形成了一个树状的层次结构,称为类加载器的层次结构。当JVM需要加载一个类时,它会按照这个层次结构进行查找:
- 首先,由根类加载器尝试加载。
- 如果根类加载器没有加载到该类,它会“委托”给扩展类加载器尝试加载。
- 如果扩展类加载器也没有加载到,那么“委托”给应用程序类加载器尝试加载。
如果这三个内置的类加载器都没有加载到所需的类,那么才会使用自定义类加载器进行加载。这种委托机制保证了Java核心库的安全性,并且使得类加载过程更加灵活。
自定义类加载器可以介入类加载过程,实现特殊的类加载需求,例如:
- 加载加密的.class文件。
- 通过网络下载.class文件。
- 动态加载和卸载类。
使用自定义类加载器时,可以通过重写ClassLoader中的`findClass`和`loadClass`方法来实现自定义的类加载逻辑。