【无标题】

下面用最直白、面试可直接背的方式讲清楚 双亲委派机制(Parent Delegation Model)。


一、一句话定义

类加载器收到加载请求 → 先交给父加载器 → 父加载不了 → 自己再加载。

目的:保证核心类安全、全局唯一、防止篡改。

"双亲"不是两个父类,是层级链上的父加载器(翻译问题)。


二、三层加载器(JDK8)

从上到下:

  1. Bootstrap ClassLoader(启动类加载器)

    • C++写的,JVM内置
    • 加载:rt.jar 核心类(java.lang.String、Object...)
    • 路径:$JAVA_HOME/lib
  2. Extension ClassLoader(扩展类加载器)

    • Java写的
    • 加载:lib/ext 或 java.ext.dirs 的扩展类
  3. Application ClassLoader(应用/系统类加载器)

    • Java写的
    • 加载:项目 classpath 下的类、第三方jar
    • 日常代码几乎都是它加载

父子关系是 组合(parent 字段),不是 Java 继承。


三、执行流程(必背)

以加载 com.example.MyClass 为例:

  1. AppClassLoader 收到请求
  2. 检查:是否已加载过? → 是,直接返回
  3. 没加载 → 委派给父:ExtClassLoader
  4. ExtClassLoader 同样:有缓存返回,没缓存 → 委派给 Bootstrap
  5. Bootstrap:
    • 在 rt.jar 找 → 找不到(因为是你自己的类)
    • 返回"加载失败"
  6. 回到 ExtClassLoader:自己路径也找不到 → 失败
  7. 回到 AppClassLoader:自己调用 findClass 加载 → 成功

总结:自下而上委派,自上而下加载;父优先,子兜底。


四、核心作用(面试高频)

  1. 安全:防止核心类被篡改

    • 你自己写一个 java.lang.String,不会被加载
    • 因为 Bootstrap 优先加载 rt.jar 里的正版 String
  2. 唯一:一个类在 JVM 中只一份

    • 全链路委派,保证不会重复加载
  3. 隔离:不同加载器的类互相隔离

    • 例如:AppClassLoader 加载的 A 类 ≠ 自定义加载器加载的 A 类

五、什么时候打破双亲委派?

默认是双亲委派,但有些场景必须打破:

  1. Tomcat:

    • 每个 Web 应用有自己的类加载器
    • 先加载自己 war 包里的类,再委派父加载器
    • 目的:Web 应用之间类隔离、热部署
  2. JDBC 驱动加载:

    • Bootstrap 加载 java.sql.Driver(接口)
    • 实现类在应用 jar 里,需要反向委派
  3. 热部署、OSGi、模块化框架

打破方式:重写 ClassLoader 的 loadClass 方法,不先委派父加载器。


六、源码核心(简化版)

java 复制代码
protected Class<?> loadClass(String name, boolean resolve)
    throws ClassNotFoundException {
    // 1. 检查是否已加载
    Class<?> c = findLoadedClass(name);
    if (c == null) {
        try {
            if (parent != null) {
                // 2. 委派父加载器
                c = parent.loadClass(name, false);
            } else {
                // 3. 父为null → 调用Bootstrap
                c = findBootstrapClassOrNull(name);
            }
        } catch (ClassNotFoundException e) {
            // 父加载失败
        }
        if (c == null) {
            // 4. 自己加载
            c = findClass(name);
        }
    }
    if (resolve) resolveClass(c);
    return c;
}

关键:loadClass 默认先委派;findClass 由子类重写实现自己的加载逻辑。


七、面试极简背诵版

  • 定义:加载类时先委派父加载器,父不能加载才自己加载。
  • 三层:Bootstrap → Ext → App。
  • 流程:自下而上委派,自上而下加载。
  • 作用:安全防篡改、全局唯一、类隔离。
  • 打破:重写 loadClass,如 Tomcat、JDBC。

相关推荐
2301_780789662 小时前
跨平台适配!SDK 游戏盾兼容全终端游戏场景
java·网络·ddos
学长毕设3 小时前
基于springboot的食品仓库管理系统
java·spring boot·后端
步行cgn4 小时前
FormHttpMessageConverter 详解:Spring MVC 中表单数据的读写转换器
java·spring·mvc
龙亘川4 小时前
构建城市公共安全数字底座:亘川智城智慧安防系统全维度解读
java·大数据·开发语言·人工智能·信息可视化
金銀銅鐵4 小时前
[Java] 用 CLI 展示 EnumMap 增删键值对时的内部变化
java·源码·ai编程
秋天的怀念_David4 小时前
第二十二夜 · 数字迷雾
java·程序人生·算法
Raas1004 小时前
AI网关部署方案?从部署到上线全流程
java·开发语言·人工智能·gateway·ai网关·企业级ai网关·企业级ai产品
niucloud-admin5 小时前
NIUCLOUD PHP SAAS上门家政使用文档:城市管理
java·前端·php
霸道流氓气质5 小时前
智能客服组件:分层意图识别、RAG Advisor 与人工转接状态机的 Vue3 + Spring AI 生产级实战
java·人工智能·spring
captain3766 小时前
MyBatis操作数据库(入门2)
java·数据库·spring boot·后端·spring·mybatis