- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
深入JVM的Class文件结构
Class文件由顺序的8位字节为基础单位构成的二进制流。各个项目严格按照顺序紧凑排列,无分隔符。
需要用8位字节以上空间数据项时按照高位在前分割成若干个8位字节存储。
只包含2种数据类型:
无符号数
表
无符号数
是class文件基本数据类型,以u1,u2,u4,u8分别代表1个字节,2个,4个,8个字节的无符号数。可以用来描述数字、索引引用、数量值、以UTF-8编码构成的字符串。
表
由多个无符号数或其他表作为数据项构成的复合数据类型。所有表以“_info”结尾。用来描述具有层次关系的复合结构数据。
其实class文件本质上就是一张表。
Class文件结构
包含magic魔数,文件版本,常量池,访问标识,类索引、父类索引与接口索引集合,字段表集合,方法表集合,属性表集合等构成
魔数
在class文件头4个字节,magic number。作用:确定该文件是否是虚拟机可接受的class文件。java的魔数统一为 0xCAFEBABE (来源于一款咖啡)。
版本号
由minorversion和majorversion组成,占用文件中第5到8字节。如
CA FE BA BE 00 00 00 32表示此版本号为50.0,十进制表示一般格式为 major.minor需要注意的是java版本号是从45开始的,大版本发布,主版本号+1.高版本的jdk能向下兼容以前版本的class文件,但不兼容以后版本的class文件。
各jdk编译后的class文件版本号如下:
常量池
紧接着版本号后就是常量池入口。是第一个出现的表类型的数据项目。由常量池容量计数值constant_pool_count及常量池constant_pool组成。constant_pool_count占2个字节。如 0×0016 即十进制的22,表示有21项常量,从1开始到21.
0有特殊含义,表示指向常量池的索引值数据不引用任何一个常量池项目。
常量池主要存放字面量Literal和符号引用Symbolic References。
字面量可能是文本字符串,或final的常量值。符号引用包括以下:
类或接口全限定名 Full Qualified Name
字段名称和描述符 Descriptor
方法名称和描述符
常量池共有11种表结构数据。
每个表均开始的第一位是u1类型的标志位,表示哪种常量类型。但每个表的结构都不相同。如类或接口的符号引用为CONSTANTClassinfo.
所有的常量池结构严格以标志位,表结构其他数据类型 顺序排列。各类型常量池表结构如下表所示:
实际中可以使用 javap -verbose XXX.class 输出字节码内容。
访问标志access_flags
u2类型,识别类或接口层次的访问信息,如class是接口或类,是否public,是否abstract,是否final等。
类索引、父类索引与接口索引集合
类索引this_class及父类索引super_class均是u2类型,接口索引集合interfaces是一组u2类型的集合。确定类的继承 关系.按照顺序排列在访问标志之后。this_class,super_class指向CONSTANT_CLASS_info常量。通过该常量可以找到 定义在CONSTANT_Utf8_info的全限定名字符串。
字段表集合field_info
紧接在interface后面的是fieldscount的计数,它是类变量和实例变量的字段的数量总和。在这个计数后面的是不同长度的fieldinfo表的序列(fieldscount指出了序列中有多少个fieldinfo表)。
描述接口或类中声明的变量,包含类级变量或实例级变量,不包含方法变量。信息包含:字段作用域、字段类型(类变量还是实例变量 static)、可变性(final)、并发可见性(volatile)、可否序列化(transient)、字段数据类型、名称等。结构如下表:
字段修饰符放在accessflags项目中,它与类中的accessflags项目是非常相似的,都是一个u2的数据类型,其中可以设置 的标志位和含义如下表所示
nameindex和descriptorindex都是对常量池的引用,分别代表着字段的简单名称及字段和方法的描述符.其中 描述符的作用是用来描述字段的数据类型、方法的参数列表(包括数量、类型以及顺序)和返回值。根据描述符规则,基本数据类型(byte、char、 double、float、int、long、short、boolean)及代表无返回值的void类型都用一个大写字符来表示,而对象类型则用字符L 加对象的全限定名来表示。
对于数组类型,每一个维度将使用一个前置的”[字符来描述,如一个
文档评论(0)