Java类的加载
Keyworkd Java 类加载, 类加载机制 , ClassLoader, 双亲委派模型,parent delegation model
我们每天都能见到太阳,时间长了便习以为常了,不会去思考,太阳光是怎么传来的。但是如果仔细的思考这个问题的话,发现不一定能解释的很清楚。
同理,我们每天用spring框架来开发Java应用,慢慢的掉入了业务开发的深渊,成了springframework 程序员,忘记了Java本质的东西。比方说Java类的加载。
1.Java类由谁加载?
Java类的加载是指,将 .class文件加载到虚拟机。加载的工作由ClassLoader以及其子类来完成。
ClassLoader分为,
BootstrapClassLoader 负责加载 java_home/jre/lit/rt.jar
ExtensionClassLoader 负责加载拓展功能的一些jar java_home/jre/lib/ext/*.jar 对应的类为 :ExtClassLoader
System ClassLoader 负责加载Classpath中的class和jar, 对应的类为: AppClassLoader
User-Definde ClassLoader 用户自定义的classloader,比如字节码加密了,自定义calssloader来加载并解密,继承ClassLoader类并重新findClass方法。
一般来说,这四种类加载器会形成一种父子关系,高层为低层的父加载器。
在进行类加载时,首先会自底向上挨个检查是否已经加载了指定类,如果已经加载则直接返回该类的引用。
如果到最高层也没有加载过指定类,那么会自顶向下挨个尝试加载,直到最下层用户自定义类加载器,如果还不能成功,就会抛出异常。
Classloader的层次关系被称为“双亲委派模型” Parents delegation model。
用户自定义classloader可以实现 class 的热替换。
2.Java类在什么时候加载?
简单来说就是当我们要使用这个类的时候,他就会加载。
初始化类,反射类,调用一个类的静态方法等
- Person p = new Person();
- Class dog = Class.forName("com.test.Dog");
- CommonUtil.doSomeThing();
注意,一个Class只会被加载一次,也就是说,只有在第一次调用Person类的方法的时候,因为Person此前没被加载过,所以执行加载,以后调用Person类,就不需要加载了。
3.如何知道JVM加载了哪些类?
要想看Jvm加载了哪些类,可以增加JVM参数,-verbose:class。这样在控制台就有输出。
假设有一个Test类,伪代码如下:
1 2 3 4 5 6 7 | main(){ Person p = new Person(); p.sayHello(); Class d = Class.forName( "com.cnblogs.Dog" ); System.out.print(d.getName()); } |
我们在运行类之前给加上-verbose:class参数,那么在控制台我们可以看到出了方法打印的信息,还能看到类加载的信息。
[Loaded com.cnblogs.test.Person from file:/D:/xxx/target/classes/]
并且是先看到类加载信息,然后才看到类执行的方法打印信息。
4. 类加载的步骤
类加载的过程分为: 装载 , 链接 , 初始化(非必须)。
装载就是找到二进制的字节码并加载到JVM,JVM通过全限定类名和类加载器完成类的加载。
加载好的类的标识是:类的全限定名 + ClassLoader实例ID。java虚拟机也是基于此来判断两个Java类是否相同,即 类全限定名相同, 且是被同一个classloader加载的。即使是同一个字节码文件,被不同的classloader加载了,也会认为是不同的类。
链接的过程中对字节码进行校验。格式是否正确,引用的类,属性是否存在。
(不存在则抛异常,NoClassDefFoundError, NoSuchMethodError, NoSuchFieldError)

【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构