JVM 标准到底如何定义类加载
内容来自JVMS Chapter 5 – Loading, Linking, and Initialization类加载、链接、初始化这是 JVM 规范中对类加载的正式描述。这不是教材版而是接近 JVM 规范原文的专业总结版。JVM 不定义类加载器的层次结构、不强制双亲委派也不定义 classpath。 它只要求类必须通过某个加载器被定义类的身份由“类名 加载器”唯一确定。 加载、链接、初始化的每个环节必须按规范精确执行。1. JVM 规范中类加载属于更大的过程Loading → Linking → Initialization加载 → 链接 → 初始化JVMS 定义类处理流程分为三大阶段1. Loading加载 2. Linking链接 2.1 Verification验证 2.2 Preparation准备 2.3 Resolution解析 3. Initialization初始化类加载只是整个过程的第一步不包含解析、初始化。2. JVM 如何定义 “类加载Loading”JVMS 定义Class loading is the process of locating a binary representation of a class or interface and transforming it into the runtime data structure inside the JVM.类加载 找到类的二进制表示并创建其在 JVM 中的运行时表示。规范强调三点1“二进制表示”不限于 .class 文件可以来自.class/JAR/网络/动态生成的字节数组如 ASM/CGLIB/数据库/加密文件JVM 标准不限制来源。2类加载器负责找到这个“二进制表示”规范中称之为defineClass findClass3加载结果是method area或 Metaspace中的 Class 对象规范描述为runtime representation of classes 类的运行时表示3. JVM 规范如何描述类加载器ClassLoader类加载器不是 Java 语言的组成部分但 JVM 规范要求The Java Virtual Machine must maintain a mapping between class loaders and the classes they have loaded.Java虚拟机必须维护类加载器与其加载的类之间的映射关系。这意味着每个类都有一个加载器标识类的身份 (className classLoader)类的身份 (className classLoader)4. JVM 标准如何描述 “类加载器之间的关系”最关键的一段The Java Virtual Machine specification does not require class loaders to follow a parent-child hierarchy.Java虚拟机规范不要求类加载器遵循父子层次结构。也就是说双亲委派不是 JVM 强制的是 Java ClassLoader 的一种“设计模式”而不是 JVM 的硬规则JVM 层面只关心“由哪个加载器加载”5. JVM 规范如何要求加载器委派parent delegation非常重要的一段The delegation model is strongly recommended but not strictly required by this specification.本规范强烈建议采用委托模型但并非严格要求。这意味着HotSpot 的默认加载器链Bootstrap → Ext/Platform → App是Launcher(JDK8)/ClassLoaders(JDK9)Java 层设计的不是 JVM 强制的容器Tomcat/OSGi可以合法地破坏它符合规范6. JVM 规范如何描述类的唯一性Class Identity规范定义类的唯一标识为Class Identity (class name defining class loader)因此同名类由两个不同 ClassLoader 加载 → 两个不同的类注意这里两个不同的ClassLoader可以是不同类型的ClassLoader也可以是同类型ClassLoader的不同实例不同类型的ClassLoader// 类型1JDK 自带的 URLClassLoaderURL url classPath.toUri().toURL();URLClassLoader urlLoader new URLClassLoader(new URL[]{url}, null);// 类型2我们自己写的 MyFileClassLoader完全不同类型MyFileClassLoader myLoader new MyFileClassLoader(classPath, null);// 加载同一个类Class? c1 urlLoader.loadClass(a7.Person);Class? c2 myLoader.loadClass(a7.Person);不同实例// 两个完全一样的 class 文件但路径不同 → 两个不同的 ClassLoaderURL url1 Paths.get(D:/MyWork/0-create/practice idea/jvm/jvm-practice/out/production/part4/).toUri().toURL();URL url2 Paths.get(D:/MyWork/0-create/practice idea/jvm/jvm-practice/out/production/part4/).toUri().toURL();// 父加载器都设为 null直属 Bootstrap这样更纯粹也可以设为 getSystemClassLoader()URLClassLoader loader1 new URLClassLoader(new URL[]{url1}, null);URLClassLoader loader2 new URLClassLoader(new URL[]{url2}, null);// 加载同一个全限定名的类Class? clazz1 loader1.loadClass(a7.v1.User);Class? clazz2 loader2.loadClass(a7.v2.User);不能相互赋值、不能 instanceof、不能强制转型这是 OSGi、Tomcat 多版本隔离的理论基础。7. JVM 如何描述“类加载触发条件”规范要求类只有在首次主动使用时才必须加载主动使用包括new 对象调用静态方法访问静态字段非 final反射 Class.forName引用 Class.forName初始化子类会触发父类加载JVM 启动加载 main 类8. JVM 对生命周期的强制要求重要JVM 必须保证类必须按需加载lazy loading类只能被加载一次每个 ClassLoader 内同一加载器加载同名类必须返回同一 Class 对象加载器之间不能冲突父和子加载器加载同名类时是两个类9. JVM 规范对 defineClass 的要求非常核心规范要求 defineClass 只做校验二进制格式将其转换为内部运行时结构绑定到当前 ClassLoader 的命名空间它不负责查找 class处理委派管理 classpath管理类路径这些都是 Java 层的 ClassLoader 负责的。10. JVM 规范明确双亲委派不是必须 | 自定义加载器合法自定义 ClassLoader从 JVM 标准的角度完全合法只要保证defineClass 的字节码合法链接验证成功不替换 java.* 核心类否则安全管理器会禁止不与系统类冲突除非故意隔离下面是一个打破双亲委派的例子基于jdk17import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; public class MyClassLoaderJdk17 extends ClassLoader { private final String classPath; private final String targetPackagePrefix com.test; public MyClassLoaderJdk17(String classPath) { super(MyClassLoaderJdk17.class.getClassLoader()); // parent app loader this.classPath classPath; } Override public Class? loadClass(String name) throws ClassNotFoundException { // JPMS 下绝不能尝试加载 java.*否则报错 if (name.startsWith(java.) || name.startsWith(jdk.) || name.startsWith(javax.)) { return super.loadClass(name); } // 对业务包破坏双亲委派 if (name.startsWith(targetPackagePrefix)) { synchronized (getClassLoadingLock(name)) { Class? loaded findLoadedClass(name); if (loaded ! null) return loaded; try { return findClass(name); } catch (Exception ignored) { } } } // 其余保持默认委派 return super.loadClass(name); } Override protected Class? findClass(String name) throws ClassNotFoundException { try { String file classPath / name.replace(., /) .class; byte[] bytes Files.readAllBytes(Paths.get(file)); return defineClass(name, bytes, 0, bytes.length); } catch (IOException e) { throw new ClassNotFoundException(name, e); } } }因此Tomcat 的 WebAppClassLoaderSPI 的 ThreadContextClassLoaderOSGi 的 BundleClassLoader完全符合 JVM 标准。

相关新闻

多维融合破局,智测锂电未来 —— 维视智造 VisionCon 重磅发布锂电蓝膜检测创新方案

多维融合破局,智测锂电未来 —— 维视智造 VisionCon 重磅发布锂电蓝膜检测创新方案

2026 年 1 月 22 日,古城西安迎来行业盛会 —— 由雅时国际商讯倾力打造的 VisionCon 视觉系统设计技术会议盛大启幕,本次会议以 “机器视觉赋能数智化生产” 为核心主题,汇聚全球机器视觉领域的技术先锋、行业大咖与企业代表,聚焦…

2026/7/6 17:13:21 阅读更多 →
新手必看:aarch64汇编启动文件.S常见写法梳理

新手必看:aarch64汇编启动文件.S常见写法梳理

以下是对您提供的博文内容进行深度润色与结构重构后的技术文章。整体遵循您的全部要求:✅ 彻底去除AI痕迹,语言自然如资深嵌入式工程师面对面讲解;✅ 打破模块化标题束缚,以逻辑流替代“引言/小节/总结”套路;✅ 核心知…

2026/7/3 19:08:52 阅读更多 →
代码级解析:如何快速部署一套海外版外卖系统

代码级解析:如何快速部署一套海外版外卖系统

在上一篇宏观探讨了海外外卖平台的架构与策略后,本文将深入技术实践层面。我们将以流行的“微服务前后端分离”架构为例,探讨如何利用React等技术栈,快速构建一个高可用的外卖平台核心模块,并附上关键代码示例。 一、 技术栈选型与…

2026/7/4 14:58:39 阅读更多 →

最新新闻

Dify搭建智能客服工作流:设计到生产环境部署

Dify搭建智能客服工作流:设计到生产环境部署

我之前文章已经搭建好dify,这里直接用一、1、这里主页选择聊天机器人2、在工作室找到你的新建聊天机器人,点进去3、用户输入-知识检索-llm-直接回复4、先添加LLM模型qwen3:8b5、添加嵌入式模型bge-m36、Dify 的 Marketplace里面主要是一些扩展插件二、返…

2026/7/7 11:35:07 阅读更多 →
OpenCore Legacy Patcher:为老款Mac赋予新生的内存注入技术方案

OpenCore Legacy Patcher:为老款Mac赋予新生的内存注入技术方案

OpenCore Legacy Patcher:为老款Mac赋予新生的内存注入技术方案 【免费下载链接】OpenCore-Legacy-Patcher Experience macOS just like before 项目地址: https://gitcode.com/GitHub_Trending/op/OpenCore-Legacy-Patcher 面对苹果官方对旧款Mac的macOS支持…

2026/7/7 11:35:07 阅读更多 →
一位主播的进化史:从手忙脚乱到从容掌控多平台直播

一位主播的进化史:从手忙脚乱到从容掌控多平台直播

一位主播的进化史:从手忙脚乱到从容掌控多平台直播 【免费下载链接】obs-multi-rtmp OBS複数サイト同時配信プラグイン 项目地址: https://gitcode.com/gh_mirrors/ob/obs-multi-rtmp 你是否也曾经历过这样的场景?晚上8点,直播即将开始…

2026/7/7 11:31:06 阅读更多 →
高效文档下载神器:一键获取30+平台文档的智能解决方案

高效文档下载神器:一键获取30+平台文档的智能解决方案

高效文档下载神器:一键获取30平台文档的智能解决方案 【免费下载链接】kill-doc 看到经常有小伙伴们需要下载一些免费文档,但是相关网站浏览体验不好各种广告,各种登录验证,需要很多步骤才能下载文档,该脚本就是为了解…

2026/7/7 11:29:05 阅读更多 →
计算机毕业设计之基于jsp民宿网站的设计与实现

计算机毕业设计之基于jsp民宿网站的设计与实现

本论文主要论述了如何使用JSP技术开发一个民宿网站,本系统将严格按照软件开发流程进行各个阶段的工作,采用B/S架构,面向对象编程思想进行项目开发。在引言中,作者将论述民宿网站的当前背景以及系统开发的目的,后续章节…

2026/7/7 11:29:05 阅读更多 →
统一过程RUP:微软的“四阶段疗法“

统一过程RUP:微软的“四阶段疗法“

统一过程RUP:微软的"四阶段疗法" 开篇:软件开发的"问诊流程" 想象一下你去医院看病: 第一步:挂号问诊 医生问你的症状、病史,做初步检查。 第二步:开检查单 医生根据初步判断,开化验单、B超单等检查。 第三步:确诊 根据检查结果,确定你得了什…

2026/7/7 11:27:05 阅读更多 →

日新闻

鸿蒙新特性:图片画廊与轮播导航——构建沉浸式图片浏览体验

鸿蒙新特性:图片画廊与轮播导航——构建沉浸式图片浏览体验

图片浏览是移动应用中最高频的场景之一。从社交应用的照片流到电商平台的商品图集,从旅游应用的景点相册到摄影作品展示——用户对图片浏览的体验要求不断提高:流畅的切换动画、直观的缩略图导航、便捷的收藏操作、自动播放模式。HarmonyOS NEXT ArkUI 虽…

2026/7/7 0:05:16 阅读更多 →
24V DC-DC降压芯片PW2312B/PW2815,SOT23-6到SOP8-EP方案对比

24V DC-DC降压芯片PW2312B/PW2815,SOT23-6到SOP8-EP方案对比

24V稳压芯片完整选型指南 PW8600 PW75XX PW2815 PW2312B LDODC/DC全方案 一、24V稳压方案概述 24V直流电源在工业自动化、门禁系统、电梯控制、汽车电子、LED驱动、监控设备等场景中应用极广,是最常见的中压直流母线电压。要将24V母线稳定降压至下游MCU、传感器…

2026/7/7 0:05:16 阅读更多 →
RAG+知识图谱混合检索与Graph RAG核心对比

RAG+知识图谱混合检索与Graph RAG核心对比

做企业RAG落地的团队,往往容易卡在一容易踩坑的选型难题: 当需求单纯靠向量RAG搞不定、单纯靠知识图谱也搞不定,必须同时依赖「文本语义理解 实体关系推理」时,到底是做「向量图谱混合检索」就够了,还是必须上「Grap…

2026/7/7 0:07:19 阅读更多 →

周新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/6 8:11:50 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/6 8:11:52 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/6 6:52:56 阅读更多 →

月新闻