Class类文件的结构

Class文件是一株以8个字节为单位的二进制流。各个数据项目严格按照顺序紧凑的排列在文件之中,中间没有任何的分隔符,当遇到占用的空间大于8个字节时,会按照高位在前的方式进行分割,分割单位还是8个字节。

Class文件格式采用一种类似于C语言结构体的伪结构体来存储数据,这种伪结构中只有两种数据类型:无符号数和表

  • 无符号数:属于基本的数据类型,以u1,u2,u4,u8分别代表1个字节,2个字节,4个字节,8个字节的无符号数,他可以用来描述索引,数字,数量值或者按照utf8彪马构成字符串值。
  • 表:属于复合数据类型,是由多个基础类型或者表组合而成。为了区分表和基础数据类型,通常表的命名都是以“_info”结尾的。表示描述的是具有层次关系的数据。整个Class文件本质上也可以看做是一张表。
ClassFile {
u4 magic; //Class 文件的标志
u2 minor_version;//Class 的小版本号
u2 major_version;//Class 的大版本号
u2 constant_pool_count;//常量池的数量
cp_info constant_pool[constant_pool_count-1];//常量池
u2 access_flags;//Class 的访问标记
u2 this_class;//当前类
u2 super_class;//父类
u2 interfaces_count;//接口
u2 interfaces[interfaces_count];//一个类可以实现多个接口
u2 fields_count;//Class 文件的字段属性
field_info fields[fields_count];//一个类会可以有个字段
u2 methods_count;//Class 文件的方法数量
method_info methods[methods_count];//一个类可以有个多个方法
u2 attributes_count;//此类的属性表中的属性数
attribute_info attributes[attributes_count];//属性表集合
}

魔数与Class文件的版本

魔数:每个Class文件的前四个直接被称为魔数。

作用:确定这个文件是否是一个被虚拟机接收的Class文件。

为什么不是用文件的扩展名来进行虚拟机的识别标志?

因为文件的扩展名可以被用户随意更改。但是魔数是嵌入在文件头的,不会改变。

Class文件的版本号:紧跟魔数后边的四个字节,这四个字节中前两个字节是次版本号,后两个是主版本号。高版本可以兼容低版本的Class文件。

注意:可以使用WinHex软件打开Class文件,查看分析字节对应的内容。

常量池

常量池:紧接着主次版本号,u2,两个字节表示常量池的数量,从1开始计算,原因是将第0项空出来表示不引用常量池中任何项目。是与其他项目关联最多的数据类型,也是Class文件空间中最大的项目。

常量池主要存放两种常量:字符量和符号引用。

字符量:如字符串,声明时final类型的变量等。

符号引用:属于编译原理上的概念,包括三种,类和接口的全限定名,字段的名称和描述符,方法的名称和描述符。

常量池中的每一项都是一个表,17种表中,表开始的第一位是一个u1类型的标志位,代表当前这个常量属于哪种常量类型。

Java程序中如果定义了超过64kb英文的字符的变量或方法名,将会无法编译。

javap:一个专门用于分析Class文件的字节码工具,可以通过-verbose参数输出的.class文件内容。

访问标志

在常量池结束之后,紧接着的两个字节代表访问标志,这个标志用于识别一些类或者接口层次的访问信息,包括这个Class是类还是接口,访问权限是public还是private,是否是abstract,是否被final修饰等。

类索引与接口索引集合

类索引和父类索引都是u2类型的数据,而接口索引是一组u2类型的集合,Class文件通过这三种数据来确定类的继承关系。

类索引用于确定这个类的全限定名,父类索引用于确定这个类的父类的全限定名。

接口索引就是用来描述这个类实现了哪几种接口。集合中的顺序是按照implements后面的接口顺序。

类索引,父类索引,接口索引都是按照顺序排列在访问标志之后。

类索引和父类索引的索引值指向了一个类型是CONSTANT_Class_info的类描述符常量。这个常量的值又指向了CONSTANT_Utf8_info类型的全限定名 字符串。(全限定名例如:org/fenixsoft/clazz/TestClass;其实就是将 “.” 换成“/”)

对于接口索引集合,入口的第一项u2类型的数据为接口计数器(interfaces_count),表示索引表
的容量。如果该类没有实现任何接口,则该计数器值为0,后面接口的索引表不再占用任何字节。

字段集合

字段表:用于描述接口或者类中声明的变量。Java中的字段不包括方法内部的局部变量。

字段表结构

access_flag:字段的作用域

name_inedx:对常量池的引用,表示字段名称。

descriptor_index:对常量池的引用,表示字段和方法的描述符,用来描述字段的数据类型,方法的参数列表和返回值。

attribute_count:表示额外属性字段。

attributes:表示具体属性。

方法集合

方法表结构和字段表结构差不多,依次是访问标志,名称索引,描述符索引,属性表集合

方法访问标志

Java方法中的具体代码在属性表集合中的一个叫做Code的属性里面。

与字段表集合相对应地,如果父类方法在子类中没有被重写(Override),方法表集合中就不会出
现来自父类的方法信息。

重载方法为什么不能依靠返回值来判断?

特征签名:指一个方法中各个参数在常量池中的字段符号引用的集合。

也正是因为返回值不会包含在特征签名之中,所以Java语言里面是无法仅仅依靠返回值的不同来对一个已有方法进行重载的。

属性表集合

字段表、方法表都可以携带自己的属性集合,用来描述某种场景的专有信息。

属性表集合对属性的顺序没有要求,只是不允许有重复的属性名。

集合中的每一个属性,它的名称都要从常量池中引用一个CONSTANT_Utf8_info类型的常量来表示,而属性值的结构是自定义的。

属性列表

JVM-Class文件的结构的更多相关文章

  1. JVM(五) class类文件的结构

    概述 class类文件的结构可见下面这样图(出处见参考资料),可以参照下面的例子,对应十六进制码,找出找出相应的信息. 其中u2 , u4 表示的意思是占用两个字节和占用四个字节,下面我们将会各项说明 ...

  2. 类文件的结构、JVM 的类加载过程、类加载机制、类加载器、双亲委派模型

    一.类文件的结构 我们都知道,各种不同平台的虚拟机,都支持 "字节码 Byte Code" 这种程序存储格式,这构成了 Java 平台无关性的基石.甚至现在平台无关性也开始演变出 ...

  3. 类文件结构-----Class类文件的结构

    ①无关性的基石 “与平台无关的”得理想最终实现在操作系统的应用层上:Sun公司和其他虚拟机提供商发布了许多可以在各种不同平台上的虚拟机,这些虚拟机都可以载入和执行同一种平台无关的字节码,从而实现了程序 ...

  4. 关于Tomcat的点点滴滴(体系架构、处理http请求的过程、安装和配置、文件夹结构、设置压缩和对中文文件名称的支持、以及Catalina这个名字的由来……等)

    总结Tomcat的体系架构.处理http请求的过程.安装和配置.文件夹结构.设置压缩和对中文文件名称的支持.以及Catalina这个名字的由来--等. Tomcat和JVM: 一个Tomcat仅仅会启 ...

  5. 插件化框架解读之Class文件与Dex文件的结构(一)

    阿里P7移动互联网架构师进阶视频(每日更新中)免费学习请点击:https://space.bilibili.com/474380680 Class文件 Class文件是Java虚拟机定义并被其所识别的 ...

  6. JVM内存模型和结构详解(五大模型图解)

    JVM内存模型和Java内存模型都是面试的热点问题,名字看感觉都差不多,实际上他们之间差别还是挺大的. 通俗点说,JVM内存结构是与JVM的内部存储结构相关,而Java内存模型是与多线程编程相关@mi ...

  7. 如何组织较大项目的MVC文件夹结构

    现在还用不到,拷贝下来备用,原文链接 2016 年 9 月 第 31 卷,第 9 期 ASP.NET Core - ASP.NET Core MVC 的功能切分 作者 Steve Smith | 20 ...

  8. Class类文件的结构

    Class文件是一组以8位字节为基础单位的二进制流,各个数据项目严格按照顺序紧凑的排列在Class文件中,中间没有任何分隔符.Class文件的结构只有两种数据类型:无符号数和表.无符号数以u1.u2. ...

  9. 认识html文件基本结构

    html文件的结构:一个HTML文件是有自己固定的结构的. <html> <head>...</head> <body>...</body> ...

  10. JVM运行时内存结构

    原文转载自:http://my.oschina.net/sunchp/blog/369707 1.JVM内存模型 JVM运行时内存=共享内存区+线程内存区 1).共享内存区 共享内存区=持久带+堆 持 ...

随机推荐

  1. CSP-S2020 DP专项训练

    前言 \(\text{CPS-S2020}\) 已然临近,而 \(\text{DP}\) 作为联赛中的常考内容,是必不可少的复习要点,现根据教练和个人刷题,整理部分好题如下(其实基本上是直接搬--). ...

  2. linux 设置别名

    [root@oldboyedu45-xy data]# alias(查找别名) alias cp='cp -i' alias l.='ls -d .* --color=auto' alias ll=' ...

  3. OpenCV Error: Assertion failed (src.size == dst.size && src.channels() == dst.channels()) in cvConvertScale

    发现问题:在做kinect采集的深度图去噪的时候遇到了cvConvertScale格式转换的问题. OpenCV Error: Assertion failed (src.size == dst.si ...

  4. 「 洛谷 」P2768 珍珠项链

    珍珠项链 题目限制 内存限制:125.00MB 时间限制:1.00s 标准输入输出 题目知识点 动态规划 \(dp\) 矩阵 矩阵乘法 矩阵加速 矩阵快速幂 题目来源 「 洛谷 」P2768 珍珠项链 ...

  5. 冰点文库下载器v3.2.13绿色版

    冰点文库下载器,免费下载文档工具,无需积分也无需登陆就能自由下载百度文库.豆丁网.丁香网.电器网.MBAlib智库.爱问文档.畅享.IT168.HP009.MAX.Book118.道客巴巴.金字塔医学 ...

  6. Python 学习笔记 之 随着学习不断更新的Python特性搜集

    大小写敏感 缩进敏感--tab和空格不要混用,最好使用4个空格进行缩进.可使用vim配置缩进字符为4个空格 编写py文件时注意文件的编码,UTF-8 without BOM, 并且记得声明coding

  7. rhel6.4搭建rac前共享存储配置(iscsi+multipath+udev)

    rhel6.4搭建rac前共享存储配置(iscsi+multipath+udev) server: IP配置: 192.168.12.30 192.168.12.40   添加一个100G磁盘/dev ...

  8. 11g rac关闭、开启(顺序)

    1.关闭数据库(oracle) srvctl stop database -d rac 2.关闭集群(root) /u01/app/11.2.0/grid/bin/crsctl stop cluste ...

  9. Django项目连接多个数据库配置

    1.设置数据库连接 pip install PyMySQL 2.在项目同名目录myproject/myproject下的__init__.py添加以下代码 import pymysql pymysql ...

  10. python之把列表当做队列使用

    把列表当做队列使用,只是在列表中第一个加入的元素,第一个提取出来,拿列表当做队列用,效率并不高.在列表中最后添加或者删除元素速度很快,然而从列表里插入或者从头弹出速度却不快,因为其他所有元素都要一个一 ...