分享

class文件说明

 Dragon_chen 2017-05-05

要了解Java代码如何在Java虚拟机运行,得先了解下class文件。

每个代码文件都会编译成一个class文件。class文件是一组以8位字节为基础单位的二进制
流。各个数据项目按照顺序排列,没有分隔符。

class文件的数据结构分为无符号数和表。无符号数分为u1.u2,u4,u8。分别代表1个字节,2个字节,4个字节,8个字节的无符号数。它可以用来描述数字,索引引用,UTF8字符串值。表由多个无符号数和其他表构成。表的类型都以_info结尾。class文件有四个表,常量表cp_info,字段表field_info,方法表method_info,属性表attribute_info。这些表的作用稍后分析。

首先从class文件的头部分说起

头4个字节是"魔数"用来判断文件是否是class文件。图片文件也有“魔数”,表示文件的格式。

在"魔数"之后4个字节是class文件的版本号,再后面两个字节是次版本号,再后面两个字节是主版本号,JDK1.1支持45.0开始到45.65535的版本号。JDK1.2支持45.0到46.65535的版本号。以此类推JDK1.8支持45.0到52.65535的版本号。

在主次版本号之后的是常量池入口,一个u2类型的常量池容量计数值n,表示有多少n-1常量,从1开始。第0项常量被空出来。表示不引用常量项目(即没有常量)。每个常量都用一个cp_info常量表来表示。比如CONSTANT_Utf8_Info表示UTF-8编码的字符串(用来描述class文件中的方法和字段的名称,所以方法和变量的最大命名长度不会超过2的16次方即65535,因为这是u2类型),CONSTANT_Integer_info整型字面常量。CONSTANT_Class_info类或接口的符号引用。

常量池结束之后后两个字节是访问标志,识别类或接口层次的访问信息,比如这个class是类还是接口,是否是public类型,是否是abstract类型,是否为final类型。

再之后就是类索引,父类索引,接口索引集合,依次顺序排列在访问标志之后。类索引用于确定这个类的全限定名,指向常量池中一个constant_class_info,通过这个class_info找到Constant_utf8_info中的类的全限定名。同样的父类索引也是如此。它们都占两个字节是u2类型。二接口索引集合的入口第一项是接口计数器(u2类型)表示接口的数量。

在接口索引集合之后是字段表集合,入口处是字段数量(u2类型)是用于描述接口或类中声明的变量。它的结构如下:

   类型                                 名称                      数量
  u2                                      access_flags           1
 u2                                     name_index              1
u2                                 descriptor_index          1
u2                            attributes_count                    1
attribute_info            atributes                              atrributes_count
access_flags与访问标志是类似的,标明字段public,private,static,final,enum等标志。name_index,descriptor_index是对常量池的引用代表字段的名称和字段和方法的描述符(数据类型,枚举没有包括进来)。属性表最后再讲。

在字段表集合之后是方法表集合。入口处是方法数量(u2类型)结构和字段表集合一样。descriptro_index在这里是描述方法的返回值,类型,参数等(因为这个原因class文件可以存在两个仅返回类型不同的方法,通过描述符来区分,而java签名不是)。方法的代码在属性表中的code属性中。

属性表集合
class文件,字段表,方法表都能用到属性表集合。比如方法用到code属性来存储代码。class文件用到innerclasses存储内部类列表。sourceFile存储源文件名称(大多数情况与类名一样)下面讲code属性表。
code属性表
attribute_name_index     u2类型的属性名索引指向Constant_utf8_info.表示code属性。
attribute_length u4类型,属性长度,等于属性表的长度-(属性名称索引的长度+自身长度=6字节)
max_stack    u2类型 表示操作数栈深度的最大值,根据这个值来分配栈帧的操作栈深度。
max_locals 局部变量的存储空间。u4类型
code_length u4类型,代码长度。虽然有4个字节但是虚拟机规定一个方法不能超过65535条指令。
code u1类型,有code_length个,存储代码。
exception_table_length u2类型,异常表个数
exception_table excepiton_info类型,有exception_table_length个。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多