JVM——类加载

回顾:

java源码的运行会在编译期被编译成.class字节码文件,然后再运行期由类加载器加载到内存,最终形成虚拟机直接使用的Java类
在这里插入图片描述

一、Class文件的结构

class文件是一组以8个字节为基础的二进制流,各个数据项目严格按照顺序紧凑排列在文件中,class文件中的存储内容几乎全部是程序运行的必要数据。

1)魔数与Class文件的版本

主要是检验class文件是否可以运行。
魔数: 出现在最开始的4个字节,作用是确定这个文件是否为一个被虚拟机接收的Class文件。类似一个身份识别

class版本信息: 魔数后的4个字节,5-6是次版本号,7-8是主版本号。高版本的JDK可以兼容低版本的class文件,但低版本的JDK不能运行高版本的class文件。

2)常量池(※)

出现位置紧接着魔数和版本信息,它是Class文件的资源仓库,是Class文件结构中与其他项目关联最多的数据。

主要存放两大类常量——字面量和符号引用

  1. 字面量: 文本字符串,声明为final的常量值等(可见final类型其实在编译期就已经写入了类中

  2. 符号引用: 在编译时,java类并不知道引用类的实际内存地址,因此只能使用符号引用来代替,等到类加载时会从常量池获得对应的符号引用,在类创建或运行时才会解析到具体的内存地址中。符号引用以一组符号来描述所引用的目标,符号可以是任何形式的字面量,只要使用时能够无歧义的定位到目标即可。比如org.simple.People类引用了org.simple.Language类,在编译时People类并不知道Language类的实际内存地址,因此只能使用符号org.simple.Language(假设是这样的)。

因为常量池中常量的数值是不固定的,且有很多项目,如下图为常量池的项目类型,所以紧接着的字节码会定义常量池的容量(说明常量池的长度),常量池中的每一项常量都对应了一个表。通过常量的值查表可以的得知当前常量的类型与名称。
在这里插入图片描述
这十七种常量类型,又有各自完全独立的数据结构。比如CONSTANT_Class_info型。
在这里插入图片描述
name_index是常量池的索引值(第几个第几个)。他指向常量池中的CONSTANT_Utf8_info类型的常量,此常量代表了这个类的全限定名。

3)访问标志

常量池结束后,紧接着2个字节表示访问标志,这个标志用于识别一些类或接口层次的访问信息,比如:这个Class是类还是接口,是否是public的;是否是abstract;如果是类的话是否被声明为final等。它也对应了一张含义对照表。

4)类索引,父类索引接口索引集合

Class文件由这三项数据确定这个类的继承关系。类索引用于确定这个类的全限定类名,父类索引用于确定这个类父类的全限定类名(只有一个,因为java不支持多继承),接口索引集合,用于确定这个类是否实现了接口实现了哪些接口。

5)字段表集合(类级变量,实例级变量)

用于描述接口或类中声明的变量,比如变量的作用域,是否是static的,是否是final的,是否是volatile的,字段名称,数据类型等。修饰符用标志位来表示,字段的名字,被定义成什么类型的数据,只能引用常量池中的常量描述。(常量池中的CONSTANT_Utf8_Info型常量,同理方法也是)

6)方法表集合

与字段表集合相同,包括访问标志,名称索引,描述符索引属性表集合,其中描述符主要是用来描述字段的数据类型、或方法的参数列表和返回值。它也有自己的一套描述符规则。

7)属性表集合

Class文件,字段表,方法表,都可以携带自己的属性表集合,以描述某些场景的专有信息。
在这里插入图片描述
对于每一个属性,它的名称要从常量池中引用一个CONSTANT_Utf8_Info的常量࿰

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值