1. 首页
  2. 面试专题
  3. 文章列表
通用专题 Java/后端开发 Java 类加载机制 2026-06-14

类加载被追问到双亲委派时,真正要讲的是隔离和可控扩展

类加载题不只是背 Bootstrap、Platform、Application 三层,更要讲清类型身份、父子加载边界、打破委派的场景和热部署的资源释放风险。

Java 类加载经常被问成一串名词:Bootstrap ClassLoader、Platform ClassLoader、Application ClassLoader、双亲委派。很多回答能把层级背出来,却解释不了为什么 Web 容器、SPI、插件系统和热部署会刻意绕开默认路径。真正有区分度的地方,不是记住类加载器名字,而是理解它在管理“代码边界”。

在 JVM 里,一个类的身份不只由全限定类名决定,还由加载它的 ClassLoader 一起决定。也就是说,同一个包名、同一个类名,只要由不同加载器加载,在 JVM 看来就可能是两个不同的类型。这个规则听起来抽象,但它解释了很多线上问题:为什么插件里明明有同名接口却强转失败,为什么热部署后旧对象迟迟不释放,为什么容器能让不同应用依赖不同版本的库。

双亲委派解决的是可信基础和共享

双亲委派的大意是:一个类加载器收到加载请求时,先交给父加载器尝试,父加载器加载不了,自己再加载。这样做不是为了显得优雅,而是为了让 Java 核心类库由更上层、更可信的加载器加载,避免应用随便放一个同名的 java.lang.String 就覆盖系统类。

它还带来共享效果。公共基础类由上层加载器统一加载,下层应用看到的是同一份类型,避免每个模块各自加载一份基础类导致类型割裂。面试里如果只说“为了安全”,还不够;更完整的说法是:双亲委派同时维护了核心类可信、基础类共享和类型边界稳定。

为什么有些场景要打破它

工程系统并不总是希望所有类都向上委派。Web 容器要让多个应用隔离依赖版本,插件平台要让插件可以独立安装和卸载,SPI 机制要让核心框架反过来发现应用侧实现。这些场景里,默认的父优先策略不一定够用。

比如 JDBC 驱动、日志实现、Web 应用里的业务类,常常需要通过线程上下文类加载器或子加载器优先策略来完成发现。这里不是“破坏规则”,而是为了让框架层和应用层能在明确边界内协作。

热部署最怕旧加载器被引用住

热部署的本质通常不是修改一个类,而是创建新的类加载器加载新版本代码,然后让旧加载器连同旧类、旧静态变量和旧对象一起被回收。如果旧线程、ThreadLocal、静态集合、定时任务或回调还引用着旧类,旧加载器就下不去,内存会慢慢涨。

所以类加载问题落到项目里,重点不是能不能手写 ClassLoader,而是能不能说清生命周期:什么时候创建加载器,谁持有它,卸载前如何停止线程和任务,如何清理静态缓存,如何避免跨加载器传递实现类对象。

面试里可以这样收束

类加载机制考察的是 Java 运行时如何组织代码边界。双亲委派保护核心类和公共类型一致性;容器、SPI、插件化会在受控条件下调整委派方向;一旦涉及热部署和多版本依赖,就必须考虑类型身份、资源释放和内存泄漏。能讲到这些,类加载就不再是背诵题,而是后端工程里的模块隔离问题。