JVM类加载机制详解

发布时间 - 2026-01-10 23:09:39    点击率:

一、先看看编写出的代码的执行过程:

二、研究类加载机制的意义

从上图可以看出,类加载是Java程序运行的第一步,研究类的加载有助于了解JVM执行过程,并指导开发者采取更有效的措施配合程序执行。

研究类加载机制的第二个目的是让程序能动态的控制类加载,比如热部署等,提高程序的灵活性和适应性。

三、类加载的一般过程

原理:双亲委托模式

1、寻找jre目录,寻找jvm.dll,并初始化JVM;

2、产生一个Bootstrap Loader(启动类加载器);

3、Bootstrap Loader自动加载Extended Loader(标准扩展类加载器),并将其父Loader设为Bootstrap Loader。

4、Bootstrap Loader自动加载AppClass Loader(系统类加载器),并将其父Loader设为Extended Loader。

5、最后由AppClass Loader加载HelloWorld类。

四、类加载器的特点

1、运行一个程序时,总是由AppClass Loader(系统类加载器)开始加载指定的类。

2、在加载类时,每个类加载器会将加载任务上交给其父,如果其父找不到,再由自己去加载。

3、Bootstrap Loader(启动类加载器)是最顶级的类加载器了,其父加载器为null.

五、类加载器的获取

很容易,看下面例子

public class HelloWorld { 
   public static void main(String[] args) { 
     HelloWorld hello = new HelloWorld(); 
     Class c = hello.getClass(); 
     ClassLoader loader = c.getClassLoader(); 
     System.out.println(loader); 
     System.out.println(loader.getParent()); 
     System.out.println(loader.getParent().getParent()); 
   } 
}

打印结果:

sun.misc.Launcher$AppClassLoader@19821f 
sun.misc.Launcher$ExtClassLoader@addbf1 
null 

从上面的结果可以看出,并没有获取到ExtClassLoader的父Loader,原因是Bootstrap Loader(启动类加载器)是用C语言实现的,找不到一个确定的返回父Loader的方式,于是就返回null。 

六、类的加载

类加载有三种方式:

1、命令行启动应用时候由JVM初始化加载

2、通过Class.forName()方法动态加载

3、通过ClassLoader.loadClass()方法动态加载

三种方式区别比较大,看个例子就明白了:

package zhongqiu.common.base;
public class ClassLoadDemo {
 static {
 System.out.println("ClassLoadDemo静态初始化块执行了!");
 }
 public static void main(String[] args) throws ClassNotFoundException {
 ClassLoader loader2 = ClassLoadDemo.class.getClassLoader();
 System.out.println(loader2);
 // 使用ClassLoader.loadClass()来加载类,不会执行初始化块
 // loader2.loadClass("zhongqiu.test.Test");
 // 使用Class.forName()来加载类,默认会执行初始化块
 // Class.forName("zhongqiu.test.Test");
 // 使用Class.forName()来加载类,并指定ClassLoader,初始化时不执行静态块
 Class.forName("zhongqiu.test.Test", false, loader2);
 }
}

七、自定义ClassLoader

package zhongqiu.common.base.classload; 
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
public class MyClassLoader {
 @SuppressWarnings("resource")
 public static void main(String[] args)
  throws MalformedURLException, ClassNotFoundException, IllegalAccessException, InstantiationException {
 URL url = new URL("file:/D:/javaworkspace/JavaCommon/src/");
 ClassLoader myloader = new URLClassLoader(new URL[] { url });
 Class c = myloader.loadClass("zhongqiu.common.base.classload.Test");
 Test t3 = (Test) c.newInstance();
 }
}

在Java.lang包里有个ClassLoader类,ClassLoader 的基本目标是对类的请求提供服务,按需动态装载类和资源,只有当一个类要使用(使用new 关键字来实例化一个类)的时候,类加载器才会加载这个类并初始化。一个Java应用程序可以使用不同类型的类加载器。例如Web Application Server中,Servlet的加载使用开发商自定义的类加载器, java.lang.String在使用JVM系统加载器,Bootstrap Class Loader,开发商定义的其他类则由AppClassLoader加载。在JVM里由类名和类加载器区别不同的Java类型。因此,JVM允许我们使用不同的加载器加载相同namespace的java类,而实际上这些相同namespace的java类可以是完全不同的类。这种机制可以保证JDK自带的java.lang.String是唯一的。

八、为什么要使用这种双亲委托模式呢?

因为这样可以避免重复加载,当父亲已经加载了该类的时候,就没有必要子ClassLoader再加载一次。

考虑到安全因素,我们试想一下,如果不使用这种委托模式,那我们就可以随时使用自定义的String来动态替代java核心api中定义类型,这样会存在非常大的安全隐患,而双亲委托的方式,就可以避免这种情况,因为String已经在启动时被加载,所以用户自定义类是无法加载一个自定义的ClassLoader。

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持!


# jvm  # 类加载  # JVM类加载机制  # 详解JVM类加载机制及类缓存问题的处理方法  # JVM类加载机制原理及用法解析  # 一文读懂Jvm类加载机制  # 深入理解JVM之类加载机制详解  # 通俗讲解JVM的类加载机制  # java虚拟机JVM类加载机制原理(面试必问)  # 面试必时必问的JVM 类加载机制详解  # 一篇文章弄懂JVM类加载机制过程以及原理  # 加载  # 自定义  # 其父  # 找不到  # 设为  # 并将  # 可以看出  # 要使  # 自动加载  # 有个  # 是由  # 才会  # 很容易  # 就没  # 第二个  # 三种  # 考虑到  # 这种情况  # 就可  # 有必要 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 如何在云主机上快速搭建网站?  如何在VPS电脑上快速搭建网站?  微信小程序 input输入框控件详解及实例(多种示例)  Laravel如何设置定时任务(Cron Job)_Laravel调度器与任务计划配置  详解Oracle修改字段类型方法总结  PythonWeb开发入门教程_Flask快速构建Web应用  Python图片处理进阶教程_Pillow滤镜与图像增强  桂林网站制作公司有哪些,桂林马拉松怎么报名?  Laravel如何使用Blade组件和插槽?(Component代码示例)  HTML透明颜色代码怎么让下拉菜单透明_下拉菜单透明背景指南【技巧】  如何在Windows虚拟主机上快速搭建网站?  浅谈Javascript中的Label语句  Laravel如何实现图片防盗链功能_Laravel中间件验证Referer来源请求【方案】  Laravel如何实现文件上传和存储?(本地与S3配置)  Laravel项目结构怎么组织_大型Laravel应用的最佳目录结构实践  如何用好域名打造高点击率的自主建站?  详解jQuery中基本的动画方法  Laravel怎么生成二维码图片_Laravel集成Simple-QrCode扩展包与参数设置【实战】  Laravel怎么在Controller之外的地方验证数据  Laravel的辅助函数有哪些_Laravel常用Helpers函数提高开发效率  iOS验证手机号的正则表达式  学生网站制作软件,一个12岁的学生写小说,应该去什么样的网站?  网站制作软件有哪些,制图软件有哪些?  详解jQuery中的事件  网站视频制作书签怎么做,ie浏览器怎么将网站固定在书签工具栏?  如何在景安服务器上快速搭建个人网站?  Swift中swift中的switch 语句  Laravel如何正确地在控制器和模型之间分配逻辑_Laravel代码职责分离与架构建议  如何在服务器上配置二级域名建站?  Laravel如何实现全文搜索功能?(Scout和Algolia示例)  微信小程序 require机制详解及实例代码  Claude怎样写结构化提示词_Claude结构化提示词写法【教程】  如何在万网自助建站平台快速创建网站?  Javascript中的事件循环是如何工作的_如何利用Javascript事件循环优化异步代码?  如何用5美元大硬盘VPS安全高效搭建个人网站?  百度浏览器网页无法复制文字怎么办 百度浏览器复制修复  JavaScript常见的五种数组去重的方式  Python企业级消息系统教程_KafkaRabbitMQ高并发应用  如何用花生壳三步快速搭建专属网站?  高端建站三要素:定制模板、企业官网与响应式设计优化  Laravel如何创建和注册中间件_Laravel中间件编写与应用流程  Windows10如何删除恢复分区_Win10 Diskpart命令强制删除分区  php485函数参数是什么意思_php485各参数详细说明【介绍】  三星、SK海力士获美批准:可向中国出口芯片制造设备  JS弹性运动实现方法分析  Internet Explorer官网直接进入 IE浏览器在线体验版网址  Laravel如何实现数据导出到PDF_Laravel使用snappy生成网页快照PDF【方案】  html文件怎么打开证书错误_https协议的html打开提示不安全【指南】  太平洋网站制作公司,网络用语太平洋是什么意思?  Laravel如何实现多表关联模型定义_Laravel多对多关系及中间表数据存取【方法】