当前位置: 首页 > news >正文

Java类加载那些事

Java源文件(.java文件)被编译器编译后变为字节码形式的类文件(.class文件),Java类加载的过程就是JVM加载.class的二进制文件并且放到内存中,将数据放到方法区,并且在堆区构造一个java.lang.class对象,并且完成类的初始化的过程。

//下述片段引用自 Java的类加载机制是什么?

Java的类加载机制主要分为三个过程:加载、连接和初始化。

1.加载机制

Java的类加载机制主要分为三个过程:加载、连接和初始化。这三个过程的顺序是固定的,但是每个过程中的细节却是不同的。下面我们来详细介绍一下这三个过程。

1.1 加载

Java的类加载器会根据类的全限定名来加载类,当需要使用某个类时,如果该类还未被加载进内存,则需要执行一下步骤进行加载:

1.1.1. 通过类的全限定名找到对应的class文件,这里的class文件可以是.java文件经过编译之后生成的.class文件,也可以是通过其他方式生成的.class文件。

1.1.2 将class文件中的二进制数据读取到内存中,并将其转换为方法区的运行时数据结构。

1.1.3 创建由该类所属的java.lang.Class对象。该对象可以理解为,是对类的各种数据(如名称、访问修饰符、方法、成员变量等)的封装。

在加载类时,类加载器除了加载某个具体的类外,还需要将这个类所依赖的类也加入到内存中。这种依赖性是多层级的,也就是说,被依赖的类又可能会去依赖其他类,所以在加载一个类时,通常需要将其类图中所有的类都加载进来。

1.2 连接

Java虚拟机在加载类之后,需要对类进行连接,连接分为三个步骤:验证、准备和解析。

1.2.1. 验证:在这个步骤中,Java虚拟机主要确保所加载的类的正确性。验证过程主要包括文件格式验证、元数据验证、字节码验证和符号引用验证等。其目的在于确保目标.class文件的字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机运行时环境安全。

1.2.2. 准备:在准备阶段,Java虚拟机为类的静态变量分配内存,并设置变量的初始值。这里需要注意的是,在这个阶段中分配的内存并不包含那些用户自定义的初始化值,这些值在初始化阶段中进行设置。

1.2.3. 解析:Java在这个阶段中将常量池中的符号引用转为直接引用。通过符号引用,虚拟机得知该类访问其他的类或者类中的字段、方法等,但在类初始化时,需要缓存这些直接引用,以便于直接调用。

1.3 初始化

在类的准备阶段,Java虚拟机已经为静态变量分配了内存并设置了初值,但是这些静态变量”赋初值“的动作并没有完成。初始化阶段,会为静态变量设置用户自定义的初始化值,并执行类构造器<clinit>()方法,以执行初始化操作。

此时,类的准备和初始化阶段已经执行结束,Java的类加载机制总的过程也就结束了

//引用结束

注意,静态代码的初始化分为两步,连接的准备阶段包含初始化,最后又有一个初始化步骤,两者并不重叠,前者是给静态成员变量分配内存并且设置类型的初始值,后者是给静态成员变量设置用户指定的初始值。这段话有点拗口,代码来说明更清晰。

 1、父类 parent.java文件

public class Parent {static {System.out.println("Parent static block 1.");parentStaticIntVar = 3;}static Integer parentStaticIntVar = 2;static {System.out.println("Parent static block 2.");System.out.println("parentStaticIntVar=" + parentStaticIntVar);parentStaticIntVar = 4;}{System.out.println("Parent not static block 1.");parentIntVar = 30;}Integer parentIntVar = 20;public Parent(){	System.out.println("Parent construct  method .");System.out.println("parentIntVar=" + parentIntVar);}public void f(){System.out.println("parent f().");}{System.out.println("Parent not static block 2.");parentIntVar = 40;}}

2、子类 Sub.java文件

public class Sub extends Parent {static {System.out.println("Sub static block 1.");subStaticIntVar = 3;}static Integer subStaticIntVar = 2;static {System.out.println("Sub static block 2.");System.out.println("subStaticIntVar=" + subStaticIntVar);subStaticIntVar = 4;}{System.out.println("Sub not static block 1.");subIntVar = 30;}Integer subIntVar = 20;public Sub(){	System.out.println("Sub construct  method .");System.out.println("subIntVar=" + subIntVar);}public void f(){System.out.println("Sub f().");}{System.out.println("Sub not static block 2.");subIntVar = 40;}}

3、TestMain.java文件

public class TestMain {public static void main(String[] args) {System.out.println("-----class-----");System.out.println(">>>subStaticIntVar=" + Sub.subStaticIntVar);System.out.println(">>>parentStaticIntVar=" + Sub.parentStaticIntVar);System.out.println("-----instance-----");Sub s = new Sub();s.f();}}

4、输出结果

-----class-----
Parent static block 1.
Parent static block 2.
parentStaticIntVar=2
Sub static block 1.
Sub static block 2.
subStaticIntVar=2
>>>subStaticIntVar=4
>>>parentStaticIntVar=4
-----instance-----
Parent not static block 1.
Parent not static block 2.
Parent construct  method .
parentIntVar=40
Sub not static block 1.
Sub not static block 2.
Sub construct  method .
subIntVar=40
Sub f().

解读一下后可以知道静态代码块和静态变量遵循如下规则:

1、静态代码块先于构造方法执行;

2、静态代码块可以给静态成员变量赋值;

3、静态代码块之间按照先后顺序执行;

4、父类的静态代码块先于子类的静态代码块执行;

5、静态代码块先于非静态代码块执行;

6、静态代码块在第一次使用这个类的时候执行,并且只执行一次;

7、静态变量的显式赋值和静态代码块的按照先后顺序执行;

实际上每个Java源文件由编辑器编译后,会自动给类加载器追加一个类初始化方法:<clinit>(),一个类只有一个,包含静态变量的显式赋值代码和静态代码块的代码,在源文件中看起来是一个一个独立的代码块,实际上编译后都放到一个这个类初始化方法中去了。

非静态的代码块和变量的规则和上述类似。

类加载的方法>>>

1、Class.forName("")

Class<?> c = Class.forName("com.example.zhangzk.reflect.TestServiceImpl");

加载类,并且完成初始化。

2、ClassLoader.loadClass("")

Class<?> c = Thread.currentThread().getContextClassLoader().loadClass("com.example.zhangzk.reflect.TestServiceImpl");

加载类,不初始化。

加载器有哪些>>>

启动类加载器,C++编写的,进入Java世界的大门,负责加载存放在$JAVA_HOME\jre\lib下,或被-Xbootclasspath参数指定的路径中的,并且能被虚拟机识别的类库(如rt.jar,所有的java.*开头的类均被Bootstrap ClassLoader加载)。

扩展类加载器,Java编写的,父加载器为启动类加载器,该加载器由sun.misc.Launcher$ExtClassLoader实现,它负责加载$JAVA_HOME\jre\lib\ext目录中,或者由java.ext.dirs系统变量指定的路径中的所有类库(如javax.*开头的类)。

应用程序类加载器,Java编写的,父加载器为扩展类加载器,该类加载器由sun.misc.Launcher$AppClassLoader来实现,它负责加载用户类路径(ClassPath)所指定的类,开发者可以直接使用该类加载器,如果应用程序中没有自定义过自己的类加载器,一般情况下这个就是程序中默认的类加载器。

自定义类加载器,Java编写的,父加载器为应用程序类加载器,典型代表是Tomcat,为了在一个TOMCAT进程下部署多个JAVA应用程序必须要自定义类加载器,进行应用隔离。

双亲委派模型>>>

每个类加载器需要加载类的时候,先请求父类加载器来加载,一直到启动类加载器,启动类加载器是没有父类加载器的,父类加载器找不到给类才由自己来加载。

要想搞清楚Spring Boot的启动流程,必须要要知道上述区别,只有充分利用好上述差异才能精准的控制加载和初始化的过程,Spring中这些都用的出神入化了。

相关文章:

Java类加载那些事

Java源文件&#xff08;.java文件&#xff09;被编译器编译后变为字节码形式的类文件&#xff08;.class文件&#xff09;&#xff0c;Java类加载的过程就是JVM加载.class的二进制文件并且放到内存中&#xff0c;将数据放到方法区&#xff0c;并且在堆区构造一个java.lang.clas…...

QSplitter分裂器

QSplitter QSplitter 是 Qt 框架提供的一个小部件&#xff08;widget&#xff09;&#xff0c;用于在用户界面中创建可拖动的分割窗口&#xff0c;允许用户调整子部件的大小和布局。它可以将父部件分割为多个可调整大小的子部件&#xff0c;使用户能够自定义界面的布局和大小。…...

pgsql 时区查看和修改

建议使用UTC时区&#xff0c;或者和linux、后端程序的时区保持一致&#xff0c;否则容易出现时间的差别。 pgsql的时间字段有一个带时区的timestamp with time zone&#xff0c;如果业务涉及多个时区&#xff0c;建议使用这个字段。 相关链接参考&#xff1a; linux时区设置和…...

el-table 表格表头、单元格、滚动条样式修改

.2023.11.21今天我学习了如何对el-table表格样式进行修改&#xff0c;如图&#xff1a; 运用的两个样式主要是 1.header-cell-class-name&#xff08;设置表头&#xff09; 2.class-name&#xff08;设置行单元格&#xff09; 代码如下&#xff1a; <el-table :data&quo…...

dockerDesktop使用方法

安装软件 装在C盘会容易满&#xff0c;可以装在D盘&#xff0c; "path\to\Docker Desktop Installer.exe" install -accept-license --installation-dirD:\Docker\Docker --wsl-default-data-rootD:\Docker\data并且在软件的设置的Docker Engine里添加阿里镜像源…...

[Ubuntu]RT810xE--网线已拔出--问题解决

0 环境 ubuntu 22.04.3 LTSDell Inspiron 15 5547windows/ubuntu 双系统 1 问题说明 Dell 笔记本安装的 Ubutun 系统&#xff0c;有线网络无法使用&#xff0c;一直显示 “网线已拔出”。 网上一查&#xff0c;才了解到主要原因&#xff1a;网卡驱动安装错误。系统默认安装…...

美国DDoS服务器:如何保护你的网站免遭攻击?

​  在当今数字化时代&#xff0c;互联网已经成为人们生活中不可或缺的一部分。随着互联网的普及和发展&#xff0c;网络安全问题也日益严重。其中&#xff0c;DDoS攻击是目前最常见和具有破坏性的网络攻击之一。那么&#xff0c;如何保护你的网站免遭DDoS攻击呢?下面将介绍…...

R语言数据缩放-1到1

目录 普通scale -1到1限定范围scale 普通scale R语言实战&#xff1a;scale&#xff08;&#xff09;函数 - 知乎 (zhihu.com) scale(x, center TRUE, scale TRUE) 过程&#xff1a; 对每个变量&#xff08;列&#xff09;计算平均值&#xff08;mean&#xff09;和标准…...

C语言第二十五弹--打印菱形

C语言打印菱形 思路&#xff1a;想要打印一个菱形&#xff0c;可以分为上下两部分&#xff0c;通过观察可以发现上半部分星号的规律是 1 3 5 7故理解为 2对应行数 1 &#xff0c;空格是4 3 2 1故理解为 行数-对应行数-1。 上半部分代码如下 for (int i 0;i < line;i){//上…...

PyTorch微调终极指南1:预训练模型调整

如今&#xff0c;在训练深度学习模型时&#xff0c;通过根据自己的数据微调预训练模型来进行迁移学习&#xff08;transfer learning&#xff09;已成为首选方法。 通过微调这些模型&#xff0c;我们可以利用他们的专业知识并使它们适应我们的特定任务&#xff0c;从而节省宝贵…...

Uptime Kuma 企业微信群机器人告警

curl https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key693axxx6-7aoc-4bc4-97a0-0ec2sifa5aaa \-H Content-Type: application/json \-d {"msgtype": "text","text": {"content": "hello world"}}企业微信群机器人ke…...

【网络安全】-网络安全的分类详解

文章目录 介绍1. 网络层安全&#xff08;Network Layer Security&#xff09;理论实操使用VPN保护隐私 2. 应用层安全&#xff08;Application Layer Security&#xff09;理论实操使用密码管理器 3. 端点安全&#xff08;Endpoint Security&#xff09;理论实操定期更新防病毒…...

php利用ZipArchive类实现文件压缩与解压

github项目 1、Linux 安装zlib库 cd /usr/local/src wget https://zlib.net/current/zlib.tar.gz tar -zxvf zlib.tar.gz cd zlib-1.3 ./configure make && make install 2、zlib的使用 $all_name all.zip;// 创建ZipArchive对象$zip_all new ZipArchive();if ($z…...

Java面试附答案:掌握关键技能,突破面试难题!

问题&#xff1a;什么是大O表示法&#xff1f;它在Java中的应用是什么&#xff1f; 回答&#xff1a; 大O表示法是一种用来衡量算法复杂度的方法&#xff0c;它描述了算法的时间复杂度和空间复杂度的增长速度。它使用符号O(n)来表示算法的渐进时间复杂度&#xff0c;其中n表示…...

API自动化测试:如何构建高效的测试流程

一、引言 在当前的软件开发环境中&#xff0c;API&#xff08;Application Programming Interface&#xff09;扮演了极为重要的角色&#xff0c;连接着应用的各个部分。对API进行自动化测试能够提高测试效率&#xff0c;降低错误&#xff0c;确保软件产品的质量。本文将通过实…...

字母异位词分组

给你一个字符串数组&#xff0c;请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。 字母异位词 是由重新排列源单词的所有字母得到的一个新单词。 示例 1: 输入: strs [“eat”, “tea”, “tan”, “ate”, “nat”, “bat”] 输出: [[“bat”],[“nat”,“tan…...

SAP_ABAP_面试篇_关于Function Module函数的三种处理类型

关于 Function Module 这个技术点&#xff0c;在面试过程中一般会考察以下几个问题&#xff1a; 1 函数处理类型的更新模式 一般会问到异步和事务&#xff08;逻辑单元 LUW&#xff09;&#xff0c;异步函数的调试方式、SM13监控更新函数的执行过程&#xff08;V1 与 V2 模式…...

CentOS简介、ISO类型、CentOS7安装与配置以及远程连接。

目录 1.CentOS简介 2.CentOS ISO类型 3.CentOS7安装与配置 4.远程连接 1.CentOS简介 CentOS&#xff08;Community Enterprise Operating System&#xff0c;中文意思是社区企业操作系统&#xff09;是Linux发行版之一&#xff0c;它是来自于Red Hat Enterprise Linux依照…...

Audition 2024 24.0.0.46(音频剪辑)

Audition 2024是一款非常棒的音频编辑和混合软件&#xff0c;提供了广泛的工具和功能&#xff0c;用于创建、编辑、混合和设计音效。这款软件旨在加速音频和视频制作工作流程&#xff0c;提供具有原始音效的高质量混音。其界面构成清晰&#xff0c;操作简便&#xff0c;适合专业…...

Hive小文件处理

MR任务 mr任务参考链接 set hive.exec.reducers.max3 set hive.exec.dynamic.partition.mode true; --使用动态分区时&#xff0c;设置为ture。 set hive.exec.dynamic.partition.mode nonstrict; --动态分区模式&#xff0c;默认值&#xff1a;strict&#xff0c;表示必须…...

Z-Image-GGUF快速部署指南:ComfyUI中一键加载阿里开源模型

Z-Image-GGUF快速部署指南&#xff1a;ComfyUI中一键加载阿里开源模型 1. 项目简介 Z-Image是阿里巴巴通义实验室开源的高质量文生图AI模型&#xff0c;类似于Stable Diffusion等主流图像生成模型。本指南将详细介绍如何在ComfyUI环境中快速部署GGUF量化版本的Z-Image模型。 …...

别再纠结了!FreeRTOS、uC/OS-II、RT-Thread到底怎么选?给嵌入式新手的保姆级指南

嵌入式RTOS选型实战指南&#xff1a;从需求分析到项目落地的全流程决策 当你面对一个全新的嵌入式项目时&#xff0c;选择哪个实时操作系统&#xff08;RTOS&#xff09;往往成为第一个技术决策难题。市场上主流的FreeRTOS、uC/OS-II和RT-Thread各有特色&#xff0c;但网上大多…...

告别激活烦恼:KMS_VL_ALL_AIO智能激活脚本全方位指南

告别激活烦恼&#xff1a;KMS_VL_ALL_AIO智能激活脚本全方位指南 【免费下载链接】KMS_VL_ALL_AIO Smart Activation Script 项目地址: https://gitcode.com/gh_mirrors/km/KMS_VL_ALL_AIO 还在为Windows和Office激活而反复折腾吗&#xff1f;每次重装系统后都要面对复杂…...

告别“跟风学“!AI系统班7大模块,带你从0到1成为全栈开发者

本文指出&#xff0c;AI时代的红利不属于盲目跟风学习者。文章分析了学习者常遇到的四大问题&#xff1a;缺乏规划、理论与实践脱节、学用结合困难、缺少反馈指导。为解决这些问题&#xff0c;作者推荐了一套系统化的AI学习路线&#xff0c;包含7大模块&#xff1a;必备基础、核…...

Qwen3.5-9B算法学习伙伴:动态规划与LSTM原理详解

Qwen3.5-9B算法学习伙伴&#xff1a;动态规划与LSTM原理详解 1. 引言&#xff1a;你的AI算法学习助手 算法学习对很多人来说是个充满挑战的过程。面对复杂的数学推导和抽象概念&#xff0c;我们常常需要一个能随时解答疑问、用通俗语言解释原理的学习伙伴。Qwen3.5-9B大模型正…...

家庭无线网络技术对比与组网优化指南

1. 无线家庭网络技术全景解析二十年前&#xff0c;当第一代Wi-Fi路由器开始进入家庭时&#xff0c;谁能想到今天的智能家居设备会如此依赖无线连接&#xff1f;作为从业十余年的网络工程师&#xff0c;我见证了从HomeRF到Wi-Fi 6的技术演进历程。本文将深入剖析四种主流无线家域…...

为AI智能体构建可治理的语义执行层:安全、合规与可控实践

1. 项目概述&#xff1a;为AI智能体系统构建一个可治理的“语义执行层”如果你正在构建或使用基于大语言模型的智能体&#xff08;Agent&#xff09;系统&#xff0c;比如让AI帮你自动执行代码、调用API、处理文件&#xff0c;那么你肯定遇到过这个核心难题&#xff1a;如何确保…...

F-RAM技术原理、优势与应用场景解析

1. F-RAM技术原理与核心特性解析铁电随机存取存储器&#xff08;Ferroelectric Random Access Memory&#xff0c;简称F-RAM&#xff09;是一种基于铁电材料极化特性的非易失性存储技术。与传统存储器相比&#xff0c;F-RAM在物理结构和工作原理上有着本质区别。1.1 铁电效应与…...

Nginx等保测评避坑指南:数据备份、冗余与‘不适用’项到底怎么判?

Nginx等保测评实战解析&#xff1a;数据备份、冗余设计与"不适用"项判定逻辑 在等保测评的实际操作中&#xff0c;Nginx作为反向代理和Web服务器的角色定位&#xff0c;常常让测评人员和安全顾问在"数据备份恢复"、"冗余设计"等关键项的判定上陷…...

Windows Cleaner:彻底告别C盘爆红的智能清理解决方案

Windows Cleaner&#xff1a;彻底告别C盘爆红的智能清理解决方案 【免费下载链接】WindowsCleaner Windows Cleaner——专治C盘爆红及各种不服&#xff01; 项目地址: https://gitcode.com/gh_mirrors/wi/WindowsCleaner 还在为Windows系统C盘空间不足而烦恼吗&#xff…...