> For the complete documentation index, see [llms.txt](https://gitbook.fantasticmao.cn/tech/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://gitbook.fantasticmao.cn/tech/java/jvm/lei-jia-zai-ji-zhi.md).

# 类加载机制

## 双亲委派模型

双亲委派模型的工作机制：如果一个 ClassLoader 收到了加载类的请求，它会首先将这个请求递归委派给 parent ClassLoader，并且最终请求会委派给 BootStrap ClassLoader，只有当 parent ClassLoader 无法加载这个类的时候，children ClassLoader 才会尝试自己去加载。

```
          +---------------------+
          |BootStrap ClassLoader|
          +---------------------+
                    ^
                    |
          +--------------------+
          |Platform ClassLoader|
          +--------------------+
                    ^
                    |
        +-----------------------+
        |Application ClassLoader|
        +-----------------------+
            /               \
           /                 \
+----------------+     +----------------+
|User ClassLoader|     |User ClassLoader|
+----------------+     +----------------+
```

使用双亲委派模型的好处是使被 ClassLoader 加载类具有了一种优先级的层次关系，例如 `java.util.Object` 类只需被 Bootstrap ClassLoader 加载一遍即可，同时在程序中获取的所有 Object 类都会是同一个类。

## 破坏双亲委派模型

双亲委派模型本身也存在一些缺陷：例如，当在基础类库中需要调用业务层代码的时候，使用加载基础类库的类加载器（例如 BootStrap ClassLoader）便会无法加载到业务层的类。为了解决这个问题， Java 设计团队引入了线程上下文加载器（Thread Context ClassLoader），可以通过 `java.lang.Thread` 的 `setContextClassLoader()` 设置线程的上下文类加载器。

在追求程序的动态性时，双亲委派模型也会成为阻碍。在实现「代码热替换」、「模块热部署」等功能的时候，需要在平级的类加载器中查找和加载类，在这一点上便是破坏了双亲委派模型的原则。
