Skip to content

双亲委派模型

一、定义与加载流程

1. 核心规则

当一个类加载器收到加载类的请求时,不会自己先去加载,而是向上委托给父加载器处理;父加载器重复该逻辑,一直委托到顶层启动类加载器。 只有所有父加载器都无法加载该类时,当前子加载器才会尝试自己加载。

2. 完整流转顺序(以自定义类加载器加载Student为例)

  1. 自定义类加载器 → 委托父加载器AppClassLoader
  2. AppClassLoader → 委托父加载器ExtClassLoader
  3. ExtClassLoader → 委托父加载器BootStrap启动类加载器
  4. BootStrap查找jre/lib,找不到Student类,向下退回
  5. ExtClassLoader查找jre/lib/ext,找不到,退回
  6. AppClassLoader查找项目classpath,找到并加载Student

3. 核心类示例 String

我们自定义java.lang.String,加载请求会一路委托到BootStrap,它会加载rt.jar内原生String,不会使用我们自己写的类。

二、JVM采用双亲委派的两大作用

1. 保证类全局唯一,避免重复加载

父加载器成功加载后,子类不再重复加载同一个类,一个类在JVM中只存在一份Class对象,节省内存、防止类型转换异常。

2. 安全防护,防止篡改核心JDK类库

开发者无法自定义覆盖JDK核心类(如String、Object):

  • 自定义java.lang.String加载时,会先交给启动类加载器;
  • 启动类加载器加载原生rt.jar里的String;
  • 自定义的类永远不会被加载,杜绝恶意代码篡改底层API。 示例:自己写带main方法的java.lang.String,运行时报错:找不到main方法,因为执行的是原生无main的String。

三、面试简答

问:什么是双亲委派模型?为什么要设计这个机制? 答: 双亲委派是类加载器的加载规则:收到加载类请求时优先向上委托父加载器,顶层加载器找不到才由子类加载。 设计目的两点:

  1. 保证类唯一性,同一个类只会被加载一次,避免重复加载;
  2. 安全隔离,防止开发者自定义覆盖java.lang等核心基础类,保护JDK底层API不被篡改。

Powered by VitePress 1.6.4 | 持续更新中