双亲委派模型通过加载路径隔离、包名校验和类身份绑定保障安全:bootstrap加载器独占java.*类,非bootstrap加载器定义时直接抛securityexception,且类唯一性由“加载器+全限定名”决定。

双亲委派模型不是靠“检查”或“拦截恶意代码”来保障安全,而是通过加载路径的强制隔离、定义权限的硬性限制和类身份的双重绑定,从源头堵死核心类被替换的可能。
加载请求必须先交给 Bootstrap 类加载器
当任何类加载器(比如 AppClassLoader)收到 java.lang.String 这样的请求时,它不会去扫描 classpath 或本地 jar,而是立即向上委托:App → Platform → Bootstrap。Bootstrap 是 JVM 底层用 C++ 实现的,只认 $JAVA_HOME/lib 下的 java.base 模块(Java 9+)或 rt.jar(Java 8)。只要该类在可信路径中存在,就直接返回已加载的 Class 实例——你的自定义 String 类连字节码都不会被读取。
非 Bootstrap 加载器禁止定义 java.* 类
JVM 在 defineClass 阶段内置包名校验:
- 如果当前加载器不是 Bootstrap,且全限定名以 java.、javax. 或 sun. 开头,直接抛 SecurityException
- 这个校验不依赖委派流程,但双亲委派让它几乎不可能被触发——因为正常流程下,这类请求根本到不了自定义加载器的 defineClass 方法
类的唯一性由“加载器 + 全限定名”共同决定
即使绕过委派强行加载一个同名类(例如用反射调用 defineClass),JVM 仍视其为完全独立的类型:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- new java.lang.String() 创建的对象,类型是 Bootstrap 加载的 Class
- 你“造出来”的 java.lang.String 是另一个 Class 实例
- 二者无法赋值、无法转型,调用 equals() 会抛 ClassCastException
这种隔离不是语法层面的限制,而是类加载器命名空间天然形成的运行时屏障。
系统加载器只转发,不参与核心类定义
AppClassLoader 和 PlatformClassLoader 对 java.* 类的处理逻辑非常干净:
- 只调用 findSystemClass(name) 向 Bootstrap 请求
- 绝不尝试从本地路径读取字节码
- 也绝不调用自己的 findClass()
这个方法是 JVM 内部实现的白名单接口,只响应受信包,对非法请求返回 null 或抛异常,不留注入入口。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










