JVM——Java类加载机制总结

JVM——Java类加载机制总结1 类加载器的组织结构转载请注明出处 http blog csdn net seu calvin article details 类加载器 ClassLoader 是具有层次结构的 也就是父子关系 其中 Bootstrap 是所有类加载器的父亲 1 Bootstrapcla 启动类加载器当运行 Java 虚拟机时 这个类加载器被创建

1. 类加载器的组织结构

转载请注明出处:JVM——Java类加载机制总结_SEU_Calvin的博客-CSDN博客

类加载器 ClassLoader是具有层次结构的,也就是父子关系。其中,Bootstrap是所有类加载器的父亲

(1)Bootstrapclass loader 启动类加载器

当运行Java虚拟机时,这个类加载器被创建,它负责加载虚拟机的核心类库,如java.lang.*等。

(2)Extensionclass loader:标准扩展类加载器

用于加载除了基本 API之外的一些拓展类

(3)AppClassLoader加载应用程序和程序员自定义的类

运行下面的程序,结果也显示出来了:

JVM——Java类加载机制总结

从运行结果可以看出加载器之间的父子关系,ExtClassLoader的父Loader返回了null

原因是BootstrapLoader(启动类加载器)是用C语言实现的,找不到一个确定的返回父Loader的方式。

2. 类的加载机制

类被加载到虚拟机内存包括加载、链接、初始化几个阶段。其中链接又细化分为验证、准备、解析。

这里需要注意的是,解析阶段在某些情况下可以在初始化阶段之后再开始,这是为了支持Java的运行时绑定。各个阶段的作用整理如下:

 

2.1 加载阶段

加载阶段可以使用系统提供的类加载器(ClassLoader)来完成,也可以由用户自定义的类加载器完成,开发人员可以通过定义类加载器去控制字节流的获取方式

1通过类的全名产生对应类的二进制数据流

2)将这些二进制数据流转换为方法区的运行时数据结构

3)创建代表这个类的java.lang.Class对象。作为方法区这些数据的访问入口

 

2.2 链接阶段(实现 Java 的动态性的重要一步)

1验证:验证阶段的主要目的是确保class文件字节流的正确性,要验证比如class文件格式规范、这个类是否继承了final类、不能把一个父类对象赋值给子类数据类型等等。

2准备:准备阶段为方法区中的静态变量分配内存空间。并将其赋值为初始值,所有原始类型的值都为0。如float0f int0boolean0、引用类型为null

3解析:解析阶段把符号引用解析为直接引用

符号引用是一个字符串,它唯一标识一个类、一个字段、一个方法等目标。

而直接引用对于类变量、类方法指的是指向方法区的指针,然后对于实例方法、实例对象来说就是偏移量,比如一个实例方法,子类中方法表中的偏移量和父类是一致的,这个偏移量可以确定某个方法的位置。

 

2.3 初始化

到了初始化阶段,才是真正执行用户定义程序代码。在初始化阶段就是执行类构造器方法的过程,工作包括赋值类变量、静态语句块的合并

//定义在静态语句块之后的变量可以赋值,但不能访问 public class Test{ static{ i=0;//給变量赋值,可以通过编译 System.out.print(i);//这句编译器会提示非法向前引用 } static int i=1; } 

初始化过程会被触发的条件汇总:

1)使用new关键字实例化对象、访问一个类的静态字段静态方法的时候。

2对类进行反射调用的时候。

3)当初始化子类时,如果发现其父类还没有进行过初始化,则进行父类的初始化

 

【关于构造器方法拓展知识】(可以不看)

1)类构造器

()
方法与类的构造函数不同,它不需要显式调用父类构造,虚拟机会保证在子类

()
方法执行之前,父类的

()
方法已经执行完毕。因此在虚拟机中的第一个执行的

()
方法的类肯定是java.lang.Object

2)由于父类的

()
方法先执行,也就意味着父类中定义的静态语句块要优先于子类的变量赋值操作。

3

()
方法不是必须的,如果一个类中没有静态语句,那么编译器可以不为这个类生成

()
方法。

4接口中不能使用静态语句块,和类不同的是,执行接口的

()
方法不需要先执行父接口

()
方法。只有当父接口中定义的变量被使用时,父接口才会被初始化。另外,接口的实现类在初始化时也一样不会执行接口的

()
方法。

5)虚拟机会保证一个类的

()
方法在多线程环境中被正确加锁和同步,可能会导致阻塞。

3. 类加载的三种方式

1)由 new 关键字创建一个类的实例。

2)调用 Class.forName() 方法,通过反射加载类。

3)调用某个ClassLoader实例的loadClass()方法。

 

三者的区别汇总如下:

1)方法12都是使用的当前类加载器。方法3是用户指定的类加载器加载

2)方法1是静态加载,23是动态加载。

3)对于两种动态加载,如果程序需要类被初始化,就必须使用Class.forName(name)的方式

Class.forName(className); //实际上是调用的是: Class.forName(className, true, this.getClass().getClassLoader());//第二个参为true即默认类需要初始化,初始化会触发目标对象静态块的执行和静态变量的初始化
ClassLoader.loadClass(className); //实际上调用的是: ClassLoader.loadClass(name, false);//第二个参数即默认得到的class还没有进行链接,意味着不进行初始化等系列操作,即静态代码块不会执行 

JVM——Java类加载机制总结

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/227103.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月16日 下午9:56
下一篇 2026年3月16日 下午9:56


相关推荐

  • 计算机网络之ip、子网掩码、网络号、主机号等概念解析

    计算机网络之ip、子网掩码、网络号、主机号等概念解析在工作中谈论到计算机网络时,有几个经常出现的术语,比如:ip、子网掩码、网段等等。之前对这些概念的理解都比较模糊,只知其大概意思,随着工作中遇到的网络问题越来越多,有必要详细理解一下计算机网络的基础知识了。这篇文章就先介绍几个计算机网络领域的专业术语。IP地址ip这个词是计算机网络中出现频率最高的了,甚至只要使用过电脑的人都知道这个词。IP地址全程是互联网协议地址(英文:InternetPr…

    2022年6月24日
    40
  • VGGNet 总结

    VGGNet 总结本文是对 VeryDeepConv ScaleImageRe 的论文解读和总结 该论文发表于 ICLR2015 由牛津大学视觉几何组 VisualGeomet 和 DeepMind 公司提出 这也是 VGG 名字的由来 自 2015 年发表至今 已有超过 7K 的引用量 是 ILSVRC 2014 中定位任

    2026年3月26日
    1
  • goland2021.4激活码_通用破解码

    goland2021.4激活码_通用破解码,https://javaforall.net/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

    2022年3月17日
    377
  • 揭秘Agent框架:高效优势与潜在风险全解析

    揭秘Agent框架:高效优势与潜在风险全解析

    2026年3月13日
    1
  • 数据挖掘-层次聚类

    数据挖掘-层次聚类微信搜索 二十同学 公众号 欢迎关注一条不一样的成长之路层次聚类 hierarchical 算法极为简单 有 N 多节点 最开始认为每个节点为一类 然后找到距离最近的节点 两两合并 合并后的两个节点的平均值作为新的节点 继续两两合并的过程 直到最后都合并成一类 下图表明了聚类的过程 距离最近的节点合并 第一步中 如果有两对节点距离一样 那就同时合并 层次聚类过程如果用数据挖掘工具来做 如 SPSS 一般会生成一个树形图 那么我们可以根据分析问题的具体情况 选

    2026年1月15日
    2
  • 视频识别车牌号(Python)

    视频识别车牌号(Python)提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档文章目录前言 使用步骤 总结一、前言视频识别车牌号(有视频和代码)二、使用步骤直接上代码#导入所需要的库fromhyperlprimport*importcv2importnumpyasnp#定义保存图片函数#image:要保存的图片名字#addr;图片地址与相片名字的前部分#num:相片,名字的后缀。int类型defsave_image(i..

    2022年5月20日
    87

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号