【注释和反射】类加载的过程

继上一篇博客【注释和反射】获取class类实例的方法-CSDN博客

目录

三、类加载的过程

例子


三、类加载的过程

在Java虚拟机(JVM)中,类加载是一个将类的字节码文件从文件系统或其他来源加载到JVM的内存中,并将其转换为类或接口的过程。类加载的过程主要可以分为三个步骤:加载(Loading)、链接(Linking)和初始化(Initialization)。

(1)加载(Loading):

加载是类加载过程的第一步,主要由类加载器完成。类加载器负责从文件系统、网络或其他来源读取类的字节码文件,并将其加载到JVM的内存中。加载过程主要完成以下三件事:

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

Java提供了三种类加载器:启动类加载器(Bootstrap ClassLoader)、扩展类加载器(Extension ClassLoader)和系统类加载器(System ClassLoader)。这些类加载器之间存在父子关系,但这里的父子关系并非继承关系,而是包含关系。

(2)链接(Linking):

链接过程可以细分为验证(Verification)、准备(Preparation)和解析(Resolution)三个阶段。

  1. 验证:验证阶段主要是为了确保加载的类文件信息符合JVM规范,不会危害虚拟机自身的安全。
    1. 验证的内容包括文件格式、元数据、字节码和符号引用等。
  2. 准备:准备阶段是为类的静态变量(static变量)分配内存,并设置默认的初始值。这些内存都将在方法区中进行分配。
    1. 需要注意的是,这里所说的初始值通常情况下是数据类型默认的零值,而不是被显式赋值。
  3. 解析:解析阶段是将常量池内的符号引用替换为直接引用的过程。
    1. 符号引用以一组符号来描述所引用的目标,而直接引用则是直接指向目标的指针、相对偏移量或者一个能间接定位到目标的句柄。

(3)初始化(Initialization):

初始化阶段是类加载过程的最后一步,主要完成类的静态变量的初始化工作。静态变量的初始化是由类构造器<clinit>()方法完成的。这个方法由编译器自动收集类中的所有类变量的赋值动作和静态语句块(static{}块)中的语句合并产生的。

初始化阶段,只有当类被主动使用时才会触发。主动使用的情况包括:创建类的实例、访问某个类或接口的静态变量、调用类的静态方法、反射(如Class.forName())、初始化一个类的子类(会首先初始化子类的父类)、Java虚拟机启动时被标明为启动类的类(Java Test)、JDK 7开始提供的动态语言支持等。

需要注意的是,类的加载过程必须按照顺序开始,但并非必须按照顺序完成。因为链接阶段中的某些过程(如解析)可能需要在初始化阶段中根据实际运行情况才能确定。此外,JVM规范并没有规定解析阶段一定要在初始化之前完成,只要求了在类和接口被使用前完成解析。

例子

public class Test02 {public static void main(String[] args) {A a = new A();System.out.println(A.m);}
}class A{static {System.out.println("A类的静态代码块初始化");m = 300;}static int m = 100;public A(){System.out.println("A类的无参构造初始化");}
}

当运行Test02类的main方法时,以下是详细步骤:

  1. 加载Test02:因为Test02包含main方法,它是程序的入口点,所以JVM首先加载Test02类。但是Test02类本身没有静态变量和静态代码块需要初始化,所以这一步几乎没什么要做的。

  2. 执行main方法:在main方法中,首先创建A类的一个实例a

  3. 加载A:为了创建A的实例,JVM需要加载A类。在加载类的过程中,JVM会执行以下操作:

    • 分配内存给A类的静态变量。
    • 初始化A类的静态变量。在这个过程中,首先会执行静态代码块,然后按照声明的顺序初始化静态变量
  4. 执行静态代码块:在静态代码块中,输出了“A类的静态代码块初始化”,然后将m赋值为300。但是,这里有一个关键的陷阱。

  5. 初始化静态变量m:紧接在静态代码块执行之后,静态变量m被初始化为100。这个赋值操作实际上覆盖了静态代码块中的赋值,因为静态变量的初始化语句(static int m = 100;)在静态代码块之后执行。

  6. 创建A的实例:现在,A类已经加载并初始化,可以创建其实例了。调用A的无参构造函数,输出“A类的无参构造初始化”。

  7. 输出m的值:最后,main方法中System.out.println(A.m);输出静态变量m的当前值,由于m最终被赋值为100,所以输出结果是100。

综上所述,程序的输出结果为:

A类的静态代码块初始化
A类的无参构造初始化
100

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

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

相关文章

JSON基础

JSON JavaScript Object Notation(js对象标记法) JSON定义 {"name":"Tom","age":20,"gender":"male" }JSON格式中的键必须使用双引号括上 因为其语法格式简单,层次结构鲜明,多作为数据载体在网络中进行数据传输 JSON定…

【语音识别】搭建本地的语音转文字系统:FunASR

参考自&#xff1a; 参考配置&#xff1a;FunASR/runtime/docs/SDK_advanced_guide_offline_zh.md at main alibaba-damo-academy/FunASR (github.com)参考配置&#xff1a;FunASR/runtime/quick_start_zh.md at 861147c7308b91068ffa02724fdf74ee623a909e alibaba-damo-aca…

猎聘爬虫(附源码)

废话不多说直接附源码 cookies需要替换成自己的 , 该网站在不登录的情况下只能请求到10页数据 , 想要获得完整数据需要携带登录后的cookies import requests import json from lxml import etree import os import openpyxlheaders {"Accept": "application/…

年如何在不丢失数据的情况下解锁锁定的 Android 手机?

当您忘记密码、PIN 码或图案并且想要解锁 Android 手机时&#xff0c;您可能会丢失 Android 手机上的数据。但您无需再担心&#xff0c;因为在这里&#xff0c;我们想出了几种解锁锁定的 Android 手机而不丢失数据的方法。 方法 1. 使用 Android Unlock 解锁锁定的 Android 且不…

Java中的异常和错误

Exception ArrayIndexOutOfBoundsException&#xff08;数组下标越界&#xff09; NullPionterException&#xff08;空指针异常&#xff09; ArithmeticException&#xff08;算数异常&#xff09; MissingResourceException&#xff08;丢失资源&#xff09; ClassNotFo…

记录一次WLAN Panic导致的gcore问题分析

记录一次WLAN Panic导致的gcore问题分析 背景 高通QA架构问题出现在几天前&#xff0c;测试同事大面积报出了开机后直接卡死的问题&#xff1b;经过初步分析&#xff0c;确认是进入了Guest Coredump&#xff08;gcore&#xff09; 分析 确认直接原因 解析gcore文件&#x…

信息收集分类

在信息收集中&#xff0c;需要收集的信息&#xff1a;目标主机的DNS信息、目标IP地址、子域名、旁站和C段、CMS类型、敏感目录、端口信息、操作系统版本、网站架构、漏洞信息、服务器与中间件信息、邮箱、人员、地址等。 信息收集区别 主动信息收集&#xff1a;直接与目标信息发…

mathtype设置公式编号,公式居中以及编号靠右

在word中实现&#xff1a; 1. 首先点击栏&#xff0c;选择更多栏去看 看到栏的宽度&#xff0c;然后去设置样式 在开始-样式中设置,新建样式&#xff1a; 新建样式&#xff0c;然后设置格式-制表位&#xff0c;选择对齐方式&#xff0c;居中对齐设置刚才的一半&#xff0c;右…

RK3568 学习笔记 : u-boot 千兆网络功能验证

前言 开发板型号&#xff1a; 【正点原子】 的 RK3568 开发板 使用 虚拟机 ubuntu 20.04 编译 RK3568 Linux SDK&#xff0c;生成镜像&#xff0c;烧写后&#xff0c;Linux 系统正常启动 开启后可以使用 CTRLC 进入 u-boot 本篇验证一下 u-boot 下网络功能 【正点原子】 rk…

MATLAB 运算符

MATLAB 运算符 运算符是一个符号&#xff0c;告诉编译器执行特定的数学或逻辑操作。MATLAB设计为主要在整个矩阵和数组上运行。因此&#xff0c;MATLAB中的运算符既可以处理标量数据&#xff0c;也可以处理非标量数据。MATLAB允许以下类型的基本运算- 算术运算符 关系运算符…

JavaScript:js基础1

JavaScript 一门跨平台,面向对象的脚本语言,来控制网页行文使网页可交互 JavaScript引入方式: <script>alert("Hello JS") </script>js语句必须在 <script>标签之间,在html文档中,可以在任意地方,放置任意数量的script 一般会把脚本置于 <…

Windows SMBGhost CVE-2020-0796 Elevate Privileges

SMBGhost CVE-2020-0796 Microsoft Windows 10 (1903/1909) - ‘SMBGhost’ SMB3.1.1 ‘SMB2_COMPRESSION_CAPABILITIES’ Local Privilege Escalation https://www.exploit-db.com/exploits/48267 Github https://github.com/danigargu/CVE-2020-0796 修改载荷[可选] 生成 c# …

【ARMv9 DSU-120 系列 -- Mapping for address target groups to CHI bus master ports】

文章目录 Mapping for address target groups to CHI bus master ports映射决定过程示例CHI id bit settingMapping for address target groups to CHI bus master ports 在DSU-120(DynamIQ™共享单元-120)中,地址目标组与总线主端口之间的映射关系是通过在复位时决定哪些总…

LLaMA Factory单机微调的实战教程

大家好,我是herosunly。985院校硕士毕业,现担任算法研究员一职,热衷于机器学习算法研究与应用。曾获得阿里云天池比赛第一名,CCF比赛第二名,科大讯飞比赛第三名。拥有多项发明专利。对机器学习和深度学习拥有自己独到的见解。曾经辅导过若干个非计算机专业的学生进入到算法…

23年HVV微b蓝初面经

1. 自我介绍 从项目经验 工作经历 个人技术 上面三个方面说一些就行 2. 平时学习的方式是什么&#xff0c;有没有系统学习过安全&#xff0c; web 、内网学的怎么样 学的 b 站系统的课程&#xff0c;加了很多学习圈子、论坛&#xff0c;内网只涉猎了一点&#xff0c;学习的不…

【JAVA基础之IO】字节流、字符流以及乱码问题

&#x1f525;作者主页&#xff1a;小林同学的学习笔录 &#x1f525;mysql专栏&#xff1a;小林同学的专栏 目录 1. IO概述 1.1 什么是IO 1.2 IO的分类 1.3 字节和字符流的顶级父类 2. 字节流 2.1 一切皆为字节 2.2 字节输出流【OutputStream】 2.3 FileOutputStream类…

【GUI软件】小红书关键词搜索结果批量采集

一、背景介绍 1.1 爬取目标 用python开发的爬虫采集软件&#xff0c;可自动按关键词抓取小红书笔记。 软件界面截图&#xff1a; 爬取结果截图&#xff1a; 结果截图1: 结果截图2: 结果截图3: 以上。 1.2 演示视频 软件运行演示&#xff1a; 【软件演示】小红书搜…

零信任网络安全技术雷达图3.0正式发布

伴随零信任理念的发展和实施&#xff0c;零信任技术体系的演进变革也日趋完善。易安联力图通过持续更新并优化零信任雷达图&#xff0c;以反映零信任技术在应对新型网络安全挑战中的创新和发展&#xff0c;为企业和组织提供前瞻性的技术建议&#xff0c;助力其构建更为强大和灵…

11.泛型

文章目录 1 泛型概念2. 自定义泛型结构3 泛型方法4 泛型在继承上的体现5 通配符的使用 1 泛型概念 所谓泛型就是用标识符标识不确定的类型&#xff0c;详细说就是&#xff1a;定义类或接口时用标识符表示类中某个属性的类型或者是某个方法的返回值及参数类型。泛型将在使用时&a…

探索React Router:实现动态二级路由

我有一个路由配置的二维数组&#xff0c;想根据这个数组结合路由组件来动态生成路由&#xff0c;应该怎么样实现。在 React Router 6 中渲染二级路由的方式跟 React Router 65相比有一些变化,但核心思路仍然是利用 Route 组件和路由嵌套的方式。下面是具体的步骤: 定义路由数组…