Java类加载的过程

Java 的类加载过程是怎样的? 通过加载器,Java 能够在运行时灵活加载类,实现模块化设计、插件机制等功能。文件中的字节码加载到 JVM 中,并进行验证、解析和初始化,最终使类能够使用的过程。是 Java 虚拟机(JVM)中负责将类的字节码加载到内存中的组件。Java 的类加载过程实现了字节码的动态加载、验证与管理,保证了 Java 程序的安全性和平台无关性。加载器是 Java 动态类加载机制的核心部分,允许在运行时加载类,而不是在编译时确定所有类。类加载器负责查找并加载类的字节码。Java 的类加载过程是怎样的? 阅读详情

Java虚拟机中类加载的过程包括加载、验证、准备、解析和初始化这五个阶段

一、加载

此阶段虚拟机完成3件事情:

  1. 通过一个类的全限定名来获取定义此类的二进制字节流。
  2. 将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构。
  3. 在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口。

其中,获取二进制字节流不一定是从Class文件中获取,例如:

  1. 从 ZIP 包读取,成为 JAR、EAR、WAR 格式的基础。
  2. 从网络中获取,最典型的应用是 Applet。
  3. 运行时计算生成,例如动态代理技术,在 java.lang.reflect.Proxy 使用 ProxyGenerator.generateProxyClass 的代理类的二进制字节流。
  4. 由其他文件生成,例如由 JSP 文件生成对应的 Class 类。
  5. 从数据库中读取,例如有些中间件服务器(如SAP Netweaver)可以选择把程序安装到数据库来完成程序代码在集群间的分发

二、验证

验证是连接阶段的第一步,这一阶段的目的是为了确保Class文件的字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机自身的安全。

验证阶段大致会完成4个阶段的检验动作

  1. 文件格式验证
  2. 元数据验证 
  3. 字节码验证
  4. 符号引用验证

三、准备

准备阶段是正式为类变量分配内存并设置类变量初始值的阶段,这些变量所使用的内存都将在方法区中进行分配。这里有两点需要注意一下

  1. 此时进行内存分配的仅包括类变量(被static修饰),不包括实例变量
  2. 初始值“通常情况”下是数据类型的零值
public static int value = 123;//变量value在准备阶段过后的初始值是0而不是123

特殊情况,如果类变量是常量,那么它将初始化为表达式所定义的值而不是 0

public static final int value = 123;//变量value在准备阶段过后的初始值是123

                                              表1 不同数据类型所对应的零值 

数据类型零值
int0
long0L
short(short)0
char'\u0000'
byte(byte)0
booleanfalse
float0.0f
double0.0d
referencenull

四、解析

解析阶段是虚拟机将常量池内的符号引用替换为直接引用的过程。解析阶段在某些情况下可以在初始化阶段之后再开始,这是为了支持Java语言的运行时绑定。

  • 符号引用:以一组符号来描述所引用的目标
  • 直接引用:可以是直接指向目标的指针、相对偏移量或是能间接定位到目标的句柄

五、初始化

类初始化阶段是类加载过程中的最后一步,到了初始化阶段,才真正开始执行类中定义的Java程序代码(或者说是字节码)。在准备阶段,变量已经赋值过一次系统要求的初始值,而在初始化阶段,则根据程序员通过程序制定的主观计划去初始化类变量和其他资源。初始化阶段是执行类构造器<clinit>()方法的过程

  • <clinit>()方法是由编译器自动收集类中的所有类变量的赋值动作和静态语句块中的语句合并产生的,编译器收集的顺序是由语句在源文件中出现的顺序所决定的,静态语句块中只能访问到定义在静态语句块之前的变量,定义在它之后的变量,在前面的静态句句快可以赋值,但是不能访问。
class Test{
	static {
		i = 0;
		System.out.println(i);
	}
	static int i = 1;
}
public class Demo{
	public static void main(String[] args){
		Test test = new Test();
	}
}

运行结果

  • <clinit>()方法与类的构造函数不同,不需要显示地调用父类构造器,虚拟机会保证子类的<clinit>()方法执行之前,父类的<clinit>()方法已经执行完毕。由于父类的<clinit>()方法先执行,也就意味着父类中定义的静态语句块要优先于子类的变量赋值操作。
class Father{
	public static int A = 1;
	static{
		A = 2;
	}
}
class Son extends Father{
	public static int B = A;
}
public class Demo{
	public static void main(String[] args){
		System.out.println(Son.B);
	}
}

运行结果

  • <clinit>()方法对于类和接口并不是必须的,如果一个类中没有静态语句块,也没有对变量的赋值操作,那么编译器可以不为这个类生成<clinit>()方法。
  • 执行接口中的<clinit>()方法不需要先执行父接口的<clinit>()方法,只有当父接口中定义的变量使用时,才会初始化。
  • 虚拟机会保证一个类的<clinit>()方法再多线程环境中被正确地加锁、同步。

关于类在什么情况下会初始化,可以参考这篇文章

https://blog.youkuaiyun.com/LZAlgorithm/article/details/88903017

Java基础:类加载的过程 Java类加载是将字节码文件加载到JVM内存并转换为可执行类型的过程,包含7个生命周期阶段(加载、验证、准备、解析、初始化、使用、卸载)。核心流程包括:通过ClassLoader获取字节流(加载)、验证安全性(验证)、分配静态变量内存(准备)、替换符号引用(解析)和执行初始化代码(初始化)。类加载器采用双亲委派模型确保核心类安全,其中Bootstrap、Extension和Application类加载器分别负责不同层级的加载。 阅读详情

相关推荐

MobaXterm破解14个会话限制的保姆级教程(附Python环境配置指南)

本文提供了MobaXterm破解14个会话限制的详细教程,并深入讲解了如何配置稳定的Python环境以支持相关脚本运行。通过理解软件授权机制、安全实践步骤以及许可文件的应用,帮助用户解除会话数量限制,实现高效的远程服务器管理与自动化运维。

weixin_29211309的博客 1667

Java类加载过程详解

首先我们应明确在Java中类的生命周期是什么,引用一张图像进行说明使用(Using)卸载(Unloading)

chris3will的博客 5248

【AI蛋白预测实战】零门槛在Colab上运行AlphaFold2全流程解析

本文为零基础用户提供了在谷歌Colab平台上运行AlphaFold2进行蛋白质结构预测的完整实战指南。通过ColabFold项目,用户无需本地高性能硬件,即可免费利用云端GPU完成从序列输入到3D结构生成和结果可视化的全流程,大幅降低了AI蛋白预测的技术门槛。

mqtt6iot的博客 913

Java类的加载过程

应用程序根据自身需要自定义的ClassLoader,如Tomcat、Jboss都会根据j2ee规范实现ClassLoader。

w1lgy的博客 9566

python气象数据可视化学习笔记8——利用matplotlib和ERA5数据绘制时间-高度气象综合廓线图

利用matplotlib和ERA5数据绘制时间-高度气象综合廓线图

qiuylulu的博客 8067

从零构建EtherCAT从站:SSC工具配置与TwinCAT3 PDO/SDO调试实战

本文详细介绍了从零构建EtherCAT从站的完整流程,重点讲解SSC工具配置与TwinCAT3 PDO/SDO调试实战。通过解析EtherCAT通信机制、PDO与SDO的核心概念,提供SSC工具配置技巧、XML文件生成与校验方法,以及TwinCAT3环境下的调试经验,帮助开发者高效完成EtherCAT从站开发与优化。

weixin_42520573的博客 342

Java类加载过程

Java虚拟机把描述类的数据从 Class 文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的 Java 类型,这个过程被称作虚拟机的类加载机制。在 Java 语言里面,类型的加载、连接和初始化的过程都是程序运行期间完成的,这种策略让 Java 语言进行提前编译会面临额外的困难,也会让类加载时稍微增加一些性能开销,但是却为 Java 应用提供了极高的扩展性和灵活性。Java 天生可以可以动态扩展的语言特性就是依赖于动态加载和动态连接这个特点实现的。

weixin_46058921的博客 2365

Rockchip RK3568实战:手把手教你调试I2S音频驱动(附ALSA设备树配置详解)

本文提供Rockchip RK3568平台I2S音频驱动的实战调试指南。详细解析了从硬件连接到软件配置的全过程,重点涵盖ALSA驱动框架下的设备树配置、时钟计算、DMA参数设置以及常见问题(如无声、爆音)的排查与解决方法,帮助开发者快速定位并解决音频驱动难题。

weixin_28358083的博客 499

Java类加载过程是怎么样的?

Java类加载过程可以分为加载、验证、准备、解析和初始化五个阶段。下面我会详细解释每个阶段,并给出相应的代码演示。

Blue92120的博客 1554

13. MIC配置

恒玄BES2700,支持3个MIC。

雪飞_海 928

生成式AI;语义通信技术;生成式AI辅助的云边协同算法及其可解释性

生成式AI 语义通信技术 生成式AI辅助的云边协同算法及其可解释性 一、端到端设计的物理层内生智能 二、生成式语义通信 三、生成式数字孪生网络 四、生成式AI辅助的云边协同算法及其可解释性 五、未来可能的研究方向

ZhangJiqun&191cm&85kg 430

java类的加载过程

Java 类加载机制 类从被加载到JVM中开始,到卸载为止,整个生命周期包括:加载、验证、准备、解析、初始化、使用和卸载七个阶段。 其中类加载过程包括加载、验证、准备、解析和初始化五个阶段。 类的加载过程.png 类的加载过程 加载 1、通过类加载器,加载.class文件到内存中。 2、将读取到.classs数据存储到运行时内存区的方法区。 3、然后将其转换为一个与目标类型对应...

Chain的博客 1873

UG NX二次开发(C++)-UIStyler-指定平面的对象和参数获取

在采用NXOpen C++进行二次开发时,采用Menu/UIStyler是一种很常见的方式,这样可以制作精美的界面,而且常用的块对象也集成了快速编程的代码,我们可以快速的利用这些块来定制我们需要的界面。但是,对于很多初学者可能对选择对象的获取不是很熟悉,我们本文以选择“指定平面”来讲一下如何获取选择的对象和对象的参数。另外,由于我们的UG NX二次开发学习讨论群QQ一群已满,有希望参与学习的有志之士加入我们的QQ二群:683566590。

GimiGimmy 1092

【JAVA】类加载过程,以及类加载器

启动类加载器(Bootstrap Class Loader):负责加载Java的核心类库,例如java.lang.Object等。扩展类加载器(Extension Class Loader):负责加载Java的扩展类库,例如java.lang.String等。应用程序类加载器(Application Class Loader):也称为系统类加载器,负责加载应用程序的类,例如项目中自定义的类。自定义类加载器:开发者可以根据需要编写自定义的类加载器,用于加载特定的类或者资源。

代码的魅力,根本走不出来 2203

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

Java中类加载过程详解

而我们自定义的类加载器的实例是可以被回收的,所以使用我们自定义加载器加载的类是可以被卸载掉的。一个非数组类的加载阶段(加载阶段获取类的二进制字节流的动作)是可控性最强的阶段,这一步我们可以去完成还可以自定义类加载器去控制字节流的获取方式(重写一个类加载器的。综上,解析阶段是虚拟机将常量池内的符号引用替换为直接引用的过程,也就是得到类或者字段、方法在内存中的指针或者偏移量。综上,解析阶段是虚拟机将常量池内的符号引用替换为直接引用的过程,也就是得到类或者字段、方法在内存中的指针或者偏移量。

2401_86844317的博客 2934

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

Java面试必备:Java类加载过程详解

Java虚拟机(JVM)加载Class文件到内存,并对数据进行校验、转换解析和初始化,最终形成可以被JVM直接使用的Java类型,这个过程称为类加载。

qq_58299462的博客 1104

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Java 类加载过程

加载:在该阶段,类的字节码文件被加载到内存中,并被存储在方法区中的运行时常量池内。验证:在验证阶段,对字节码文件的合法性进行检查,以确保它满足Java虚拟机的规范要求,并且不会对虚拟机产生安全风险。准备:在准备阶段,为类的静态变量分配内存,并设置默认初始值。解析:在解析阶段,将常量池中的符号引用转换为直接引用。初始化:在初始化阶段,对类的静态变量进行初始化,并执行静态代码块。使用:在使用阶段,类被加载到内存中,并可以被其他类引用和使用。

Flying_Fish_roe的博客 906

Java中的类加载过程

类的数据从Class文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型。

Black_cat_look的博客 1252

JAVA类加载过程

1. JVM类加载过程 1.概述 从类的生命周期而言,一个类包括如下阶段: 加载、验证、准备、初始化和卸载这5个阶段的顺序是确定的,类的加载过程必须按照这种顺序进行,而解析阶段则不一定,它在某些情况下可能在初始化阶段后在开始,因为java支持运行时绑定。 2. 类加载时机 加载(loading)阶段,java虚拟机规范中没有进行约束,但初始化阶段,java虚拟机严格规定了 有且只有如下5种情况必须立即进行初始化(初始化前,必须经过加载、验证、准备阶段): (1)使用new实例化对象时,读取和设置类

代码大师麦克拉瑞的博客 2191

JAVA对象创建过程和类加载过程

fill:#333;color:#333;color:#333;fill:none;加载验证准备解析初始化使用卸载。

huing的博客 828

反无人机C2指控AI大模型本地部署:从车载到指挥中心的硬件选型实战

AI大模型在军事指挥控制(C2)和反无人机等关键任务场景中的应用正加速落地,本地化部署成为保障数据安全、降低通信时延的必然趋势。然而,硬件选型往往成为决定系统成败的首要难题:算力、显存、功耗与物理形态如何精准匹配任务剖面?从车载边缘节点的轻量化推理,到区域指控中心的多路并发分析,再到大型指挥中心的算力池设计,不同层级对GPU、内存、存储及供电的需求差异巨大。模型量化策略、推理框架选择及多模态、RAG、AI Agent等增量因素,同样反向制约着硬件配置。基于实际项目经验,从算力测算方法论与避坑指南出发,解析反

weixin_34195364的博客 231

类加载过程 JAVA

自定义类加载器是为了加载在jvm三个加载器负责的目录范围之外的类/*** @Description: 自定义类加载器} //parent: 指定父加载器, AppClassLoader/ExtClassLoader/Bootstrap public MyClassLoader(ClassLoader parent , String classPath) {//要求返回的是你要加载的字节码文件的Class对象. //这里都是我们说了算的。

DarkPumpkin的博客 1067

java类加载过程和类加载器

java类加载过程和类加载器 一:类加载概述 首先我们了解一下类是怎么进入内存的,jvm把class文件加载到内存,然后对文件进行校验,转换解析和初始化变 成可以被虚拟机直接利用的java类型,这就是虚拟机的类加载机制。java类的加载,链接和初始化都是在运行阶段进行 的,这虽然会带来一定的性能开销,却在灵...

0bug0warning的博客 334

【JAVA】聊聊类加载过程

Java 通过引入字节码和 JVM 机制,提供了强大的跨平台能力,理解 Java 的类加载机制是深入 Java 开发的必要条件。本篇博文的重点是,请介绍类加载过程,什么是双亲委派模型? 一般来说,我们把 Java 的类加载过程分为三个主要步骤:加载、链接、初始化,具体行为在 Java 虚拟机规范里有非常详细的定义。首先是加载阶段(Loading),它是 Java 将字节码数据从不同的数据源读取到 JVM 中,并映射为 JVM 认可的数据结构(Class 对象),这里的数据源可能是各种各样的形态,如 jar

ZLF_1024的博客 252
上一篇: Java中对类进行初始化(主动引用,被动引用)
下一篇: 双亲委派模型
AE86上山啦
博客等级 码龄8年 5粉丝 25原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值