JVM学习-类加载
目录
1.类文件结构
2.类加载器
3.类加载的三个阶段
3.1加载
3.2链接
3.2.1验证
3.2.2准备阶段
3.2.3解析阶段
3.3初始化
4.拓展:反射
4.1获取类对象
4.2创建实例
4.3获取方法
4.4方法调用
1.类文件结构

2.类加载器
类加载器用来将类文件的二进制字节码加载到JVM的方法区中。有四种类加载器:

连接数据库驱动调用的类加载器:在连接数据库时会调用DriverManager类进行驱动,而DriverManager是核心类,所以会使用到启动类加载器;但数据库连接的驱动包并不在核心类库中,所以DriverManager类中有一个loadInitialDrivers()方法,内部使用了两种方式加载驱动:
第一种是SPI机制加载驱动,约定是在jar包中添加一个META-INF/services目录,在其中添加一个配置文件,文件的名称就是接口的全限定名称,数据库连接驱动就是java.sql.Driver,文件内容就是接口的实现类 ;通过ServiceLoader.load()方法根据约定的路径找到实现类;这个load方法的内部调用的是线程上下文类加载器,由于在创建线程时默认分配的是应用类加载器,所以这种机制实际上调用的是应用类加载器。第二种是使用系统变量jdbc.drivers定义的驱动类的类名加载驱动,调用Class.forName()方法加载和初始化驱动类,使用的是系统类加载器,也就是应用类加载器。
数据库连接驱动是先调用的系统类加载器再调用的应用类加载器,所以在某些情况下会打破双亲委派机制。
3.类加载的三个阶段
类加载分为三个阶段:加载、链接、初始化。链接又分为三个阶段:验证、准备、解析。
3.1加载
要注意的是,一个类的.class文件加载到方法区后变成了C++的instanceKlass文件,这个文件中包含了这个类的各种信息,然后再在堆中生成一个Class类型的对象(区分class,class是定义一个类用的;区分.class文件,这是编译生成的一个类的二进制字节码,还没有被加载),因为java不能直接访问方法区的instanceKlass,所以需要这个Class副本来供我们使用,通过反射拿到的一个类的Class对象就是这么来的,这也就是为什么这个Class对象被叫做类镜像了。

3.2链接
3.2.1验证
验证这个类转换的字节码是否符合JVM规范,并进行安全性检查,比如检查字节码中的魔数是否是Java文件的魔数。
3.2.2准备阶段
给静态变量分配空间,并设置默认值:
- 静态变量在JDK7之前是放在instanceKlass的末尾也就是方法区中,而在JDK7之后则是放在了类镜像末尾,也就是堆内存中。
- 静态变量的空间分配在准备阶段完成,而赋值则是在初始化阶段,但是final类型的静态变量比较特殊:如果是final的基本类型或字符串类型的静态变量,则分配空间和赋值都在准备阶段完成,因为对于这些类型的变量而言final说明值不会改变,已经确定了静态变量的值,所以在准备阶段会直接赋值;而如果是final的引用类型的静态变量则赋值会放在初始化阶段,因为new一个对象需要类先初始化完成后才能创建。
3.2.3解析阶段
将常量池的符号引用解析为直接引用。符号引用就是这个类虽然被加载了,但由于还没有进行解析,也就不知道这个类在内存中的位置,相当于只是一个符号;而直接引用就是经过了解析之后,知道了其在内存中的具体位置,就可以访问这个类了。
3.3初始化
类的初始化是为了确保类的结构正确并且所有的数据都已初始化为预期的状态,只有在类的初始化完成后才能在系统中正常使用这个类及其方法和属性。初始化过程主要包括给静态变量赋值、静态代码块的执行等,只有首次主动使用时才会触发初始化,初始化是懒惰的,且只进行一次。
初始化发生的时机:
- main方法所在的类会先进行初始化。
- 首次访问这个类的静态变量或静态方法时。
- 子类进行初始化时,若父类还没有初始化,则会先进行父类的初始化再进行子类的初始化。
- 当子类访问父类的静态变量时,只会触发父类的初始化。
- 当执行Class.forName方法时,会执行类加载并默认进行初始化;当然也可以给参数initialize设置为false表示不执行初始化。
- 通过new创建实例化对象时会触发初始化。
以下情况不会触发初始化:
- 访问静态常量时,因为静态常量的空间分配和赋值均在链接时的准备阶段完成。
- 使用类加载器的loadClass方法时,loadClass方法只进行加载阶段。
- 访问类对象的.class文件时不会触发初始化,因为Class对象在class文件加载到方法区后就会生成,所以在加载阶段时就已经生成。
- 创建该类的数组不会触发初始化,因为在JVM中会生成一个其他的类来表示数组类型,与原本的类无关,所以不会触发原来的类的初始化。
4.拓展:反射
反射:通过使用类对象(即堆中的Class对象)来创建实例、调用方法等。
4.1获取类对象
Class c=类名.forName();
或
Class<?> c=类名.class;
或
Class<?> c=类名.getClass();
以下操作都建立在获取了Class对象的基础上
4.2创建实例
Object o=c.newInstance();
也可以通过指定的构造器来创建实例,比如使用String的构造器来创建实例:
//先获取String类的带一个String类型参数的构造器
Constructor cst=c.getConstructor(String.class); //再通过调用构造器的newInstance方法来创建实例
Object o=cst.newInstance("abc");
4.3获取方法
//获取这个类的除继承父类的方法外的其他所有方法
Method[] m1=c.getDeclaredMethods();//获取这个类的所有公有方法
Method[] m2=c.getMethod(); //获取指定方法
Method m=c.getMethod("方法名");
4.4方法调用
//先获取指定的方法
Method m=c.getMethod("方法名"); //调用方法:
//当所调用的方法既有参数也有返回值时
Object result=m.invoke(参数集);//当所调用的方法没有返回值且无参数时
m.invoke(null);
相关文章:
JVM学习-类加载
目录 1.类文件结构 2.类加载器 3.类加载的三个阶段 3.1加载 3.2链接 3.2.1验证 3.2.2准备阶段 3.2.3解析阶段 3.3初始化 4.拓展:反射 4.1获取类对象 4.2创建实例 4.3获取方法 4.4方法调用 1.类文件结构 2.类加载器 类加载器用来将类文件的二进制字节码加载到JV…...
PyCharm中如何使用不同的虚拟环境
1. 简介 有些项目用老的运行环境,而有些项目用新的运行环境,那么我们在运行这些代码(比如跑对比实验的时候)如何进行切换呢,这时候就可以使用虚拟环境啦 2. 虚拟环境的创建 首先启动Anaconda Prompt 并在其中执行如…...
Unity Live Capture 中实现面部捕捉同步模型动画
Unity Face Capture 是一个强大的工具,可以帮助你快速轻松地将真实人脸表情捕捉到数字模型中。在本文中,我们将介绍如何在 Unity Face Capture 中实现面部捕捉同步模型动画。 安装 |实时捕获 |4.0.0 (unity3d.com) 安装软件插件 安装 Live Capture 软件…...
Codeforces Round 932(div2)||ABD
A-Entertainment in MAC 题意 可以对一个字符串进行两种操作: 将字符串反转将该字符串反转后接在原串的后面。 可以进行任意次上述操作,获得字典序最小的字符串。 数据范围 t ( 1 ≤ t ≤ 500 ) t(1≤t≤500) t(1≤t≤500) n ( 2 ≤ n ≤ 1 0 9 ) n…...
基于最小二乘法的太阳黑子活动模型参数辨识和预测matlab仿真
目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 5.完整程序 1.程序功能描述 基于最小二乘法的太阳黑子活动模型参数辨识和预测matlab仿真。太阳黑子是人们最早发现也是人们最熟悉的一种太阳表面活动。因为太阳内部磁场发生变化,…...
VSCode配置cuda C++编程代码提示的详细步骤
目录 VSCode配置cuda C++编程代码提示的详细步骤: 1、cuda编译环境的安装:...
JUnit 面试题及答案整理,最新面试题
JUnit中的断言(Assert)有哪些类型? JUnit提供了多种断言类型来帮助测试代码的正确性。常见的断言类型包括: 1、assertEquals: 用于检查两个值是否相等。如果不相等,测试失败。 2、assertTrue和assertFal…...
使用Lua编写Wireshark解析ProtoBuf插件
文章目录 Wireshark Protobuf Lua-dissectorStep 1: 获取 WiresharkStep 2: 配置ProtoBuf相关设置添加ProtoBuf查找路径 Step 3 运行和调试Lua代码1. 添加Lua脚本2. 运行和调试 Step 4: 写Lua Dissector代码 :)Step 5(Optional): Decode AsGithub工程地址 Wireshark Protobuf L…...
ClickHouse副本节点数据损坏恢复
参考链接:https://blog.csdn.net/qq_42082701/article/details/127771766 参考链接:https://kb.altinity.com/altinity-kb-setup-and-maintenance/suspiciously-many-broken-parts/ # 背景CK配置为1分片2副本# 配置参数,这里我们将max_suspicious_brok…...
YOLOv9改进策略:注意力机制 | SimAM(无参Attention),效果秒杀CBAM、SE
💡💡💡本文改进内容:SimAM是一种轻量级的自注意力机制,其网络结构与Transformer类似,但是在计算注意力权重时使用的是线性层而不是点积 yolov9-c-CoordAtt summary: 972 layers, 51024476 parameters, 510…...
宝塔 安装对外服务Tomcat和JDK
一、安装Tomcat\JDK 切记1:如果选择下载节点失败,请到软件商城安装 。 切记2:提醒安装Nginx或Apache ,先点安装,进入再打叉关闭。因为Tomcat服务足够为我们搭建JavaWeb网站服务了。 切记3:Nginx占用80端口…...
rust最新版本安装-提高下载速度
1)拉取依赖包将安装脚本输出到本地rust.sh脚本中 curl --proto https --tlsv1.2 -sSf https://sh.rustup.rs > rust.sh 2)更新rust.sh脚本内容、修改源 # 编辑rust.sh vi rust.sh # 将RUSTUP_UPDATE_ROOT的值替换为: RUSTUP_UPDATE_ROOT&q…...
数据清洗与预处理:打造高质量数据分析基础
随着数据的快速增长,数据分析已经成为企业和组织的核心业务。然而,原始数据往往包含各种杂质和异常,这就需要我们进行数据清洗和预处理,以确保分析结果的准确性和可靠性。 1. 数据清洗的重要性: 数据清洗是指对原始数据进行检查、修正和完善,以消除错误、不一致性和噪声…...
Linux服务器(Debian系)包含UOS安全相关巡检shell脚本
#!/bin/bash# Define output file current_date$(date "%Y%m%d") # Gets the current date in YYYYMMDD format output_file"server_security_inspection_report_${current_date}.txt"# Empty the file initially echo > $output_file# 获取巡检时间 (…...
BS4网络提取selenium.chrome.WebDriver类的方法及属性
BS4网络提取selenium.chrome.WebDriver类的方法及属性 chrome.webdriver: selenium.webdriver.chrome.webdriver — Selenium 4.18.1 documentation class selenium.webdriver.chrome.webdriver.WebDriver 是 Selenium 中用于操作 Chrome 浏览器的 WebDriver 类。WebDriver 类…...
Prompt Engineering(提示工程)
Prompt 工程简介 在近年来,大模型(Large Model)如GPT、BERT等在自然语言处理领域取得了巨大的成功。这些模型通过海量数据的训练,具备了强大的语言理解和生成能力。然而,要想充分发挥这些大模型的潜力,仅仅…...
移远通信亮相AWE 2024,以科技力量推动智能家居产业加速发展
科技的飞速发展,为我们的生活带来了诸多便利,从传统的家电产品到智能化的家居设备,我们的居家生活正朝着更智能、更便捷的方向变革。 3月14日,中国家电及消费电子博览会(Appliance&electronics World Expo…...
Java中上传数据的安全性探讨与实践
✨✨谢谢大家捧场,祝屏幕前的小伙伴们每天都有好运相伴左右,一定要天天开心哦!✨✨ 🎈🎈作者主页: 喔的嘛呀🎈🎈 目录 引言 一. 文件上传的风险 二. 使用合适的框架和库 1. Spr…...
Leetcode 17. 电话号码的字母组合
心路历程: 之前看过这道题的解法但是忘了。一开始想多重循环遍历,发现不知道写几个for循环,于是想到递归;发现递归需要记录选择的路径而不是返回节点值,想到了回溯。 回溯的解题模板:维护两个变量…...
蓝桥杯单片机快速开发笔记——独立键盘
一、原理分析 二、思维导图 三、示例框架 #include "reg52.h" sbit S7 P3^0; sbit S6 P3^1; sbit S5 P3^2; sbit S4 P3^3; void ScanKeys(){if(S7 0){Delay(500);if(S7 0){while(S7 0);}}if(S6 0){Delay(500);if(S6 0){while(S6 0)…...
使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式
一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明:假设每台服务器已…...
国防科技大学计算机基础课程笔记02信息编码
1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制,因此这个了16进制的数据既可以翻译成为这个机器码,也可以翻译成为这个国标码,所以这个时候很容易会出现这个歧义的情况; 因此,我们的这个国…...
大数据学习栈记——Neo4j的安装与使用
本文介绍图数据库Neofj的安装与使用,操作系统:Ubuntu24.04,Neofj版本:2025.04.0。 Apt安装 Neofj可以进行官网安装:Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...
C++实现分布式网络通信框架RPC(3)--rpc调用端
目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中,我们已经大致实现了rpc服务端的各项功能代…...
Mac软件卸载指南,简单易懂!
刚和Adobe分手,它却总在Library里给你写"回忆录"?卸载的Final Cut Pro像电子幽灵般阴魂不散?总是会有残留文件,别慌!这份Mac软件卸载指南,将用最硬核的方式教你"数字分手术"࿰…...
反射获取方法和属性
Java反射获取方法 在Java中,反射(Reflection)是一种强大的机制,允许程序在运行时访问和操作类的内部属性和方法。通过反射,可以动态地创建对象、调用方法、改变属性值,这在很多Java框架中如Spring和Hiberna…...
令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍
文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结: 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析: 实际业务去理解体会统一注…...
vue3+vite项目中使用.env文件环境变量方法
vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量,这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...
Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理
引言 Bitmap(位图)是Android应用内存占用的“头号杀手”。一张1080P(1920x1080)的图片以ARGB_8888格式加载时,内存占用高达8MB(192010804字节)。据统计,超过60%的应用OOM崩溃与Bitm…...
React---day11
14.4 react-redux第三方库 提供connect、thunk之类的函数 以获取一个banner数据为例子 store: 我们在使用异步的时候理应是要使用中间件的,但是configureStore 已经自动集成了 redux-thunk,注意action里面要返回函数 import { configureS…...
