JVM 触发类加载的条件有哪些?

目录

一、类加载生命周期

二、主动引用

2.1、创建类的实例

2.2、访问类的静态字段或静态方法

2.3、反射

2.4、初始化类的子类时,先初始化父类

2.5、虚拟机启动时,初始化 main 方法所在的类

2.6、动态语言支持

三、被动引用

3.1、通过子类引用父类的静态字段

3.2、访问编译期常量

3.3、通过数组定义类引用


Java 虚拟机(JVM)中,类的加载并不是随意发生的,而是由特定的触发条件决定的。什么时候加载?什么时候初始化?

这是我们必须要搞清楚的问题,尤其在复杂的应用中,弄懂类加载的时机能帮助我们避免一些潜在的性能问题和运行时错误。

在本节中,我们将详细探讨类加载的时机、主动和被动引用的区别,以及常见的类加载触发条件。

一、类加载生命周期

类加载的生命周期包括:加载(Loading)链接(Linking)初始化(Initialization)。而其中,初始化阶段是决定类是否被真正加载的关键。

JVM 在什么时候启动类加载过程呢?

主要分为主动引用被动引用两种情况。我们分别看看这两种情况在什么条件下会触发类加载。

二、主动引用

主动引用是指程序显式地使用某个类,从而触发类的加载和初始化。根据《Java 虚拟机规范》,以下六种情况会触发类的主动引用,也就是触发类加载的条件!

2.1、创建类的实例

当你使用 new 关键字创建一个类的实例时,JVM 会立即加载并初始化该类。

// 触发 MyClass 的加载和初始化
MyClass obj = new MyClass(); 

初始化流程

  1. 分配内存给 MyClass 的实例对象。

  2. 加载 MyClass 类的字节码,并执行静态代码块和静态变量赋值操作。

2.2、访问类的静态字段或静态方法

访问类的静态字段或静态方法时,也会触发类的加载和初始化。

// 触发 MyClass 的加载
System.out.println(MyClass.staticVar);  
// 触发 MyClass 的加载
MyClass.staticMethod();                

常量不会触发类加载:如果静态字段是 final 修饰的常量,它在编译期已存入常量池,因此不会触发类加载。

System.out.println(MyClass.FINAL_CONSTANT);  // 不触发类加载

2.3、反射

通过反射调用类时,也会触发类加载。 

Class<?> clazz = Class.forName("com.example.MyClass");  // 触发 MyClass 的加载

2.4、初始化类的子类时,先初始化父类

当初始化一个类时,如果它的父类尚未初始化,JVM 会先初始化父类。

public class Parent {static {System.out.println("父类初始化");}
}public class Child extends Parent {static {System.out.println("子类初始化");}
}// 先输出"父类初始化",再输出"子类初始化"
Child obj = new Child();  

2.5、虚拟机启动时,初始化 main 方法所在的类

虚拟机启动时,main 方法所在的类是程序的入口类,会被优先加载和初始化。

public static void main(String[] args) {System.out.println("主类加载");
}

2.6、动态语言支持

在 Java 7 引入的 java.lang.invoke 包中,当 MethodHandle 最终指向的类需要初始化时,也会触发类的加载。

MethodHandle handle = MethodHandles.lookup().findStatic(MyClass.class, "staticMethod", MethodType.methodType(void.class));
handle.invoke();  // 可能触发 MyClass 的加载

三、被动引用

被动引用不触发类加载。

与主动引用相对,被动引用是指访问类的某些特性时不会触发类的加载和初始化。以下是几种典型的被动引用场景。

3.1、通过子类引用父类的静态字段

如果子类只引用父类的静态字段,JVM 只会初始化父类,而不会初始化子类。

示例

// 只触发 Parent 的加载,不触发 Child 的加载
System.out.println(Child.staticVar);  

3.2、访问编译期常量

访问 final 修饰的编译期常量,不会触发类的加载。

// 不触发 MyClass 的加载
System.out.println(MyClass.FINAL_CONSTANT);  

3.3、通过数组定义类引用

通过数组引用一个类,不会触发该类的加载。

// 不触发 MyClass 的加载
MyClass[] array = new MyClass[10];  

最后,为什么需要关注类加载的时机?

  • 避免类的过早加载:过早加载可能导致不必要的内存消耗,尤其在大型应用中。

  • 延迟加载(Lazy Loading):通过延迟加载,可以在真正需要时才加载类,减少启动时间。

  • 减少类加载冲突:在模块化或插件化的应用中,合理安排类加载顺序有助于避免类冲突和类加载死锁问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/608.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

初学spring 框架(了解spring框架的技术背景,核心体现,入门案例)

目录 技术背景 为什么要学习spring 框架&#xff1f; 学习spring 框架可以解决什么问题&#xff1f; 了解spring框架的核心体现 入门案例 步骤 1 导入 依赖 2 搭建三层架构体现【根据实际情况 构建】 3 添加配置文件 Test 测试类中 从 Ioc 容器 获取 Student 对象 总…

用户界面的UML建模11

然而&#xff0c;在用户界面方面&#xff0c;重要的是要了解《boundary》类是如何与这个异常分层结构进行关联的。 《exception》类的对象可以作为《control》类的对象。因此&#xff0c;《exception》类能够聚合《boundary》类。 参见图12&#xff0c;《exception》Database…

IDEA的常用设置

目录 一、显示顶部工具栏 二、设置编辑区字体按住鼠标滚轮变大变小&#xff08;看需要设置&#xff09; 三、设置自动导包和优化导入的包&#xff08;有的时候还是需要手动导包&#xff09; 四、设置导入同一个包下的类&#xff0c;超过指定个数的时候&#xff0c;合并为*&a…

STM32-笔记39-SPI-W25Q128

一、什么是SPI&#xff1f; SPI是串行外设接口&#xff08;Serial Peripheral Interface&#xff09;的缩写&#xff0c;是一种高速的&#xff0c;全双工&#xff0c;同步的通信总线&#xff0c;并且 在芯片的管脚上只占用四根线&#xff0c;节约了芯片的管脚&#xff0c;同时为…

uniapp小程序中隐藏顶部导航栏和指定某页面去掉顶部导航栏小程序

uniappvue3开发小程序过程中隐藏顶部导航栏和指定某页面去掉顶部导航栏方法 在page.json中 "globalStyle": {"navigationStyle":"custom",}, 如果是指定某个页面关闭顶部导航栏&#xff0c;在style中添加"navigationStyle": "cus…

【电子通识】PWM驱动让有刷直流电机恒流工作

电机的典型驱动方法包括电压驱动、电流驱动以及PWM驱动。本文将介绍采用PWM驱动方式的恒流工作。 首先介绍的是什么是PWM驱动的电机恒流工作&#xff0c;其次是PWM驱动电机恒流工作时电路的工作原理。 PWM驱动 当以恒定的电流驱动电机时&#xff0c;电机会怎样工作呢&#xff1…

Mysql--运维篇--主从复制和集群(主从复制I/O线程,SQL线程,二进制日志,中继日志,集群NDB)

一、主从复制 MySQL的主从复制&#xff08;Master-Slave Replication&#xff09;是一种数据冗余和高可用性的解决方案&#xff0c;它通过将一个或多个从服务器&#xff08;Slave&#xff09;与主服务器&#xff08;Master&#xff09;同步来实现。主从复制的基本原理是&#…

Mac 删除ABC 输入法

参考链接&#xff1a;百度安全验证 Mac下删除系统自带输入法ABC&#xff0c;正解&#xff01;_mac删除abc输入法-CSDN博客 ABC 输入法和搜狗输入法等 英文有冲突~~ 切换后还会在英文状态&#xff0c;可以删除 &#xff1b;可能会对DNS 输入有影响&#xff0c;但是可以通过复…

Mac——Cpolar内网穿透实战

摘要 本文介绍了在Mac系统上实现内网穿透的方法&#xff0c;通过打开远程登录、局域网内测试SSH远程连接&#xff0c;以及利用cpolar工具实现公网SSH远程连接MacOS的步骤。包括安装配置homebrew、安装cpolar服务、获取SSH隧道公网地址及测试公网连接等关键环节。 1. MacOS打开…

Unity中对象池的使用(用一个简单粗暴的例子)

问题描述&#xff1a;Unity在创建和销毁对象的时候是很消耗性能的&#xff0c;所以我们在销毁一个对象的时候&#xff0c;可以不用Destroy&#xff0c;而是将这个物体隐藏后放到回收池里面&#xff0c;当再次需要的时候如果回收池里面有之前回收的对象&#xff0c;就直接拿来用…

【再谈设计模式】模板方法模式 - 算法骨架的构建者

一、引言 在软件工程、软件开发过程中&#xff0c;我们经常会遇到一些算法或者业务逻辑具有固定的流程步骤&#xff0c;但其中个别步骤的实现可能会因具体情况而有所不同的情况。模板方法设计模式&#xff08;Template Method Design Pattern&#xff09;就为解决这类问题提供了…

【大模型】Langchain-Chatchat-v0.3.1 的环境配置

1 Langchahin-chatchat的工程简介 本项目是利用 langchain 思想实现的基于本地知识库的问答应用&#xff0c;目标期望建立一套对中文场景与开源模型支持友好、可离线运行的知识库问答解决方案。 本项目的最新版本中可使用 Xinference、Ollama 等框架接入 GLM-4-Chat、 Qwen2-In…

jenkins的作用以及操作

一 jenkins 1.1 概念 1.2 流程 1.2.1 流程 1.2.2 配置 1.3 jenkins容器自动化部署

【UE5 C++课程系列笔记】29——在UE中使用第三方库的流程

目录 前言 步骤 一、新建插件 二、创建第三方库 三、使用第三方库 前言 主要就是介绍如何将普通C++工程生成的头文件和.dll导入到UE中去使用。 步骤 一、新建插件 1. 打开插件浏览器选项卡 2. 打开插件创建器 3. 选择“第三方库”,这里命名为“MyThirdPartyLibrary…

Mybatis——Mybatis开发经验总结

摘要 本文主要介绍了MyBatis框架的设计与通用性&#xff0c;阐述了其作为Java持久化框架的亮点&#xff0c;包括精良的架构设计、丰富的扩展点以及易用性和可靠性。同时&#xff0c;对比了常见持久层框架&#xff0c;分析了MyBatis在关系型数据库交互中的优势。此外&#xff0…

【数据结构-堆】【二分】力扣3296. 移山所需的最少秒数

给你一个整数 mountainHeight 表示山的高度。 同时给你一个整数数组 workerTimes&#xff0c;表示工人们的工作时间&#xff08;单位&#xff1a;秒&#xff09;。 工人们需要 同时 进行工作以 降低 山的高度。对于工人 i : 山的高度降低 x&#xff0c;需要花费 workerTimes…

网络传输层TCP协议

传输层TCP协议 1. TCP协议介绍 TCP&#xff08;Transmission Control Protocol&#xff0c;传输控制协议&#xff09;是一个要对数据的传输进行详细控制的传输层协议。 TCP 与 UDP 的不同&#xff0c;在于TCP是有连接、可靠、面向字节流的。具体来说&#xff0c;TCP设置了一大…

玩转大语言模型——langchain调用ollama视觉多模态语言模型

系列文章目录 玩转大语言模型——ollama导入huggingface下载的模型 玩转大语言模型——langchain调用ollama视觉多模态语言模型 langchain调用ollama视觉多模态语言模型 系列文章目录前言使用Ollama下载模型查找模型下载模型 测试模型ollama测试langchain测试加载图片加载模型…

3 前端: Web开发相关概念 、HTML语法、CSS语法

文章目录 前言:导学1 Web开发相关概念2 Web标准(网页标准)3 软件架构(CS/BS)(1)C/S: Client/Server 客户端 / 服务器端(2)B/S: Browser/Server 浏览器 / 服务器端VSCode配置前段开发环境一、HTML概念1 概念2 HTML快速入门(1)语法快速入门(2)VSCode一个 !(快捷键…

STM32如何测量运行的时钟频率

前言 环境&#xff1a; 芯片&#xff1a;STM32F103C8T6 Keil&#xff1a;V5.24.2.0 一、简介STM32F103C8T6的时钟源 ①HSI 内部高速时钟,RC振荡器&#xff0c;频率为8MHz&#xff0c;精度不高。②HSE 外部高速时钟,可接石英/陶瓷谐振器&#xff0c;频率范围为4MHz~16MHz&…