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对象被叫做类镜像了,下图的Person.class应该是Person的Class对象,InstanceKlass中的_java_mirror存的是Class对象的指针。至于Class对象里有静态成员变量是因为在JDK8和以上版本中静态成员变量就被放在了Class对象的末尾,也就是放到堆中了。

        3.2链接 

                3.2.1验证

        验证这个类转换的字节码是否符合JVM规范,并进行安全性检查,比如检查字节码中的魔数是否是Java文件的魔数。

                3.2.2准备阶段

        给静态变量分配空间,并设置默认值: 

  • 静态变量在JDK7和之前的版本中是放在instanceKlass的末尾也就是方法区中,而从JDK8开始则是放在了类镜像末尾,也就是堆内存中
  • 静态变量的空间分配在准备阶段完成,而赋值则是在初始化阶段,但是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);

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

3 CUDA硬件概述

3.1 PC 架构 首先&#xff0c;我们看看当下许多PC中都使用的酷睿2(Core2)处理器的典型架构&#xff0c;然后分析一下它是如何影响我们使用GPU 加速器的(如图 3-1所示)。 图3-1典型的酷睿2(Core2)系列处理器的结构图 由于所有的 GPU 设备都是通过 PCI-E(Peripheral Communicat…

修改约束

目录 修改约束 创建数据库 添加约束 删除约束 Oracle从入门到总裁:​​​​​​https://blog.csdn.net/weixin_67859959/article/details/135209645 修改约束 如果说表结构的修改还在可以容忍的范畴之内&#xff0c;那么约束的修改是绝对 100% 禁止的 所有的约束一定要在…

王者荣耀使用的UDP通信,十几年编程没用过的协议

缘起 最近在查阅moba相关的资料时&#xff0c;看到了一篇王者荣耀的研发同学的技术分享&#xff0c;从文章中了解到王者荣耀的通信方式是UDP通信&#xff0c;回想到整个职业生涯&#xff0c;貌似并没有用过&#xff0c;今天特地整理下。 udp技术细节 udp协议 UDP协议叫做用…

代码随想录算法训练营三刷day29 | 回溯算法之 491.递增子序列 46.全排列 47.全排列 II

三刷day29 491.递增子序列回溯三部曲 46.全排列回溯三部曲 47.全排列 II 491.递增子序列 题目链接 解题思路&#xff1a; 回溯三部曲 递归函数参数 本题求子序列&#xff0c;很明显一个元素不能重复使用&#xff0c;所以需要startIndex&#xff0c;调整下一层递归的起始位…

c语言指针(二)

文章目录 c语言指针&#xff08;二&#xff09;1.数组名的理解2.使用指针访问数组3.一维数组的传参本质 c语言指针&#xff08;二&#xff09; 1.数组名的理解 int arr[10] { 1,2,3,4,5,6,7,8,9,10 }; int* p &arr[0]这⾥我们使⽤ &arr[0] 的⽅式拿到了数组第⼀个元…

系统设计实例(一)百万级别用户系统

二、百万级别用户系统 原则&#xff1a; 尽可能地缓存数据采用无状态Web层支持多个数据中心在 CDN 中托管静态资源通过分片扩展数据层将层级拆分为独立的服务 负载均衡器 负载均衡器会将传入的流量均匀分配给在负载均衡集合中定义的Web服务器&#xff0c;用户直接连接负载均…

【C++ leetcode】双指针问题(续)

3. 202 .快乐数 题目 编写一个算法来判断一个数 n 是不是快乐数。 「快乐数」 定义为&#xff1a; 对于一个正整数&#xff0c;每一次将该数替换为它每个位置上的数字的平方和。然后重复这个过程直到这个数变为 1&#xff0c;也可能是 无限循环 但始终变不到 1。如果这个过程 结…

文件IO (File对象, 文件读写)

文件 狭义的文件: 硬盘上的文件和目录(文件夹) 广义的文件: 泛指计算机中的很多 软硬件资源 OS 中, 把很多硬件设备和软件资源抽象成了文件, 按照文件的方式来统一管理网络编程中, OS 把网卡当成了一个文件来操作 路径 绝对路径: 以盘符**(c: d: e:)**开头的路径 相对路径: 以 …

HarmonyOS ArkTS 通用事件(二十三)

通用事件目录 点击事件事件ClickEvent对象说明EventTarget8对象说明示例 触摸事件事件TouchEvent对象说明TouchObject对象说明示例 挂载卸载事件事件示例 点击事件 组件被点击时触发的事件。 事件 ClickEvent对象说明 从API version 9开始&#xff0c;该接口支持在ArkTS卡片中…

C++:继承:面向对象编程的重要特性

(❁◡❁)(●◡●)╰(*▽*)╯(*/ω&#xff3c;*)(^///^)(❁◡❁)(❁◡❁)(●◡●)╰(*▽*)╯(*/ω&#xff3c;*)(❁◡❁)(●’◡’●)╰(▽)╯(/ω&#xff3c;)(///) C&#xff1a;继承&#xff1a;面向对象编程的重要特性 前言**继承**1.继承的概念及定义1.1继承的概念1.2继…

学完Python的7大就业方向,哪个赚钱最多?

“ 我想学Python&#xff0c;但是学完Python后都能干啥 &#xff1f;” “ 现在学Python&#xff0c;哪个方向最简单&#xff1f;哪个方向最吃香 &#xff1f;” “ …… ” 相信不少Python的初学者&#xff0c;都会遇到上面的这些问题。大家都知道Python很吃香&#xff0c;薪资…

英伟达 V100、A100/800、H100/800 GPU 对比

近期&#xff0c;不论是国外的 ChatGPT&#xff0c;还是国内诸多的大模型&#xff0c;让 AIGC 的市场一片爆火。而在 AIGC 的种种智能表现背后&#xff0c;均来自于堪称天文数字的算力支持。以 ChatGPT 为例&#xff0c;据微软高管透露&#xff0c;为 ChatGPT 提供算力支持的 A…

slab分配器

什么是slab分配器&#xff1f; 用户态程序可以使用malloc及其在C标准库中的相关函数申请内存&#xff1b;内核也需要经常分配内存&#xff0c;但无法使用标准库函数&#xff1b;linux内核中&#xff0c;伙伴分配器是一种页分配器&#xff0c;是以页为单位的&#xff0c;但这个…

【考研数学】零基础全年可实操规划+网课资料分析

我理解的零基础就是一点基础也没有&#xff0c;甚至来呢最基础的求极限都不会 其实大家可以参照我的经验&#xff0c;零基础数学二&#xff0c;经过一年的学习学习&#xff0c;最后考了122分 首先大家要有自信&#xff0c;我都行你们肯定也可以&#xff01;其实考研数学真的没…

XCode升级错误:Command CompileC failed with a nonzero exit code 解决办法

升级完XCode之后&#xff0c;bulid失败&#xff0c;出现如下错误&#xff1a; 问题1&#xff1a; xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrunCommand Compi…

【性能测试】JMeter:集合点,同步定时器的应用实例!

一、集合点的定义 在性能测试过程中&#xff0c;为了真实模拟多个用户同时进行操作以度量服务器的处理能力&#xff0c;可以考虑同步虚拟用户以便恰好在同一时刻执行操作或发送请求。 通过插入集合点可以较真实模拟多个用户并发操作。 (注意&#xff1a;虽然通过加入集合点可…

2024藏在身边的冷门暴利行业,普通人掌握这个方式也能轻松加入赚取100万!适合普通人轻资产创业项目!2024新的创业机会

如果说2024创业圈流传最多的话是什么&#xff0c;那一定是&#xff1a;“阶级固化了&#xff0c;翻身太难”、“2024机会太少了&#xff0c;赚不到钱”、“经济大环境不好&#xff0c;创业寒冬”云云。 其实这些抱怨都是毫无道理的&#xff0c;无论是国内还是国外&#xff0c;对…

突破图神经网络技术瓶颈!新阶段3大创新方向大幅提高模型性能

针对传统的图神经网络在处理非结构化数据、捕捉高阶关系等方面的局限性&#xff0c;研究者们提出了众多优化方案。 这其中&#xff0c;超图神经网络、几何图神经网络、动态图神经网络作为GNN发展的前沿方向&#xff0c;不仅提供了更加丰富和灵活的方法来处理各种复杂的图数据&…

基于ssm的航空售票系统

基于SSM的航空订票系统根据功能设计划分为管理员用户和注册用户&#xff0c;从这两种用户的功能所需展开设计&#xff0c;管理员对注册用户管理、航班管理、航班时刻管理、通知公告管理、订票管理、退票管理等&#xff1b;注册用户主要是注册成功后登录&#xff0c;机票查询&am…

基于 Vue3打造前台+中台通用提效解决方案(中)

33、实现全屏展示功能 我们知道在原生dom上,提供了一些方法来供我们开启或关闭全屏: Element.requestFullscreen()Document.exitFullscreen()Document.fullscreenDocument.fullscreenElement一般浏览器 使用requestFullscreen()和exitFullscreen()来实现 早期版本Chrome浏…