类文件结构

class文件结构

  • Class文件是一组以8位字节为基础单位的二进制流,各个数据项目严格按照顺序紧凑地排列在Class文件中,中间没有添加任何分隔符。
  • 根据Java虚拟机规范的规定,Class文件格式采用一种类似于C语言结构体的伪结构来存储,这种伪结构中只有两种数据类型:无符号数和表。无符号数属于基本数据类型,以u1、u2、u4、u8来分别代表1、2、4、8个字节的无符号数。表是由多个无符号数或其他表作为数据项构成的符合数据类型,所有的表都习惯性地以“_info”结尾。
ClassFile{
magic                        u4,
minor_version                u2,
major_version                u2,
constant_pool_count            u2,
constant_pool                cp_info*constant_pool_count,
access_flags                 u2,
this_class                   u2,
super_class                  u2,
interface_count              u2,
interfaces                   u2 * interface_count,
fields_count                 u2,
fields                      field_info * fields_count,
methods_count                u2,
methods                      method_info * methods_count,
attributes_count             u2,
attributes                   attributes_info * attributes_count
}

magic(魔数) u4

  • 值为0xcafebabe,没有特别的意义,放在文件头并选取用来标记该文件是一个class文件。

minor_version/major_version(次版本号和主版本号) u2 u2

  • 高版本jdK可以向下兼容以前版本的class文件

constant_pool_count/constant_pool(常量池数量和常量池) u2

  • 计数器从1开始,第0位有特殊含义,表示指向常量池的索引值数据不引用任何一个常量池项目
  • 常量池保存了文件中类或接口相关的一切常量,字面常量(直接量),如文字字符串、final变量值,以及符号引用,如类或接口的全限定名、方法或字段的简单名称和描述符。


access_flags(访问标志) u2

  • 标识这个类或接口的访问信息。是类还是接口,是否public,是否abstract等等。两个字节一共16个标志位,目前只定义了8个,没有使用的一律为0。

类索引、父类索引与接口索引集合 u2 u2 u2表

  • 各自指向一个类型为Constant_class_info的类描述符常量,通过它的索引值找到一个Constant_utf8_info类型的常量的全限定名字符串。

字段表集合

  • 描述接口或者类中声明的类变量以及实例变量,不包括方法中的局部变量。
  • 从父类继承来的字段不会出现在字段表中。但有可能出现类中不存在的字段,如内部类中自动添加指向外部类实例的字段。
field_info
{ 
    u2      access_flags; 
    u2      name_index;     //字段的简单名称
    u2      descriptor_index;     //字段和方法的描述符
    u2      attributes_count; 
    attributes_info * attributes_cout      attributes               
} 
字段访问标志
描述符标识字符含义

方法表集合

  • 字段表集合结束后便是方法表集合。
  • 和字段表一样,使用一个u2类型的方法计数器,记录该类中方法的个数。
  • 方法的定义可以和字段表一样表达,方法的代码以字节码形式存放在Code属性里。
  • 如果父类方法没有被重写,方法表集合中就不会出现来自父类的方法信息。但有可能出现编译器自动添加的方法,如类构造器<clinit>和实例构造器<init>。
方法表的结构

属性表集合

code属性
  • 该属性里主要存放由javac编译器处理后得到的字节码指令。


    code属性结构
  1. attribute_name_index是一项指向CONSTANT_Utf8_info型常量的索引,常量值固定为“Code”,它代表了该属性的名称。
  2. attribute_length指示了属性值的长度,由于属性名称索引与属性长度一共是6个字节,所以属性值的长度固定为整个属性表的长度减去6个字节。
  3. max_stack代表了操作数栈深度的最大值。
  4. max_locals代表了局部变量表所需的存储空间,它的单位是Slot,并不是在方法中用到了多少个局部变量,就把这些局部变量所占Slot之和作为max_locals的值,原因是局部变量表中的Slot可以重用。
  5. code_length和code用来存储Java源程序编译后生成的字节码指令。code用于存储字节码指令的一系列字节流,它是u1类型的单字节,因此取值范围为0×00到0xFF,那么一共可以表达256条指令,目前,Java虚拟机规范已经定义了其中200条编码值对应的指令含义。code_length虽然是一个u4类型的长度值,理论上可以达到2^32-1,但是虚拟机规范中限制了一个方法不允许超过65535条字节码指令,如果超过了这个限制,Javac编译器将会拒绝编译。
  6. 异常表: 如果字节码从第start_pc行到第end_pc行之间(不含end_pc行)出现了类型为catch_type或其子类的异常(catch_type为指向一个CONSTANT_Class_info型常量的索引),则转到第handler_pc行继续处理,当catch_pc的值为0时,代表任何的异常情况都要转到handler_pc处进行处理。
异常表
expections属性
  • 与code平级,描述方法可能抛出的受查异常,及throws关键字后的异常。注意与上面异常表区分。
LineNumberTable属性
  • 描述Java源码行号和字节码行号的对应关系,非必须,javac时可以取消,取消的话,抛出异常时,堆栈不显示出错的行号。
LocalVariableTable属性
  • 描述栈帧中局部变量表中的变量和Java源码中定义的变量之间的关系,非必须,可以和上面一样取消。
SourceFile属性
  • 记录这个Class文件的源码文件名称,可以取消。
ConstantVaule属性
  • 通知虚拟机自动为静态变量赋值。

【final、static、static final修饰的字段赋值的区别】

  • static修饰的字段在类加载过程中的准备阶段被初始化为0或null等默认值,而后在初始化阶段(触发类构造器<clinit>)才会被赋予代码中设定的值,如果没有设定值,那么它的值就为默认值。
  • final修饰的字段在运行时被初始化(可以直接赋值,也可以在实例构造器中赋值),一旦赋值便不可更改;
  • static final修饰的字段在Javac时生成ConstantValue属性,在类加载的准备阶段根据ConstantValue的值为该字段赋值,它没有默认值,必须显式地赋值,否则Javac时会报错。可以理解为在编译期即把结果放入了常量池中。
InnerClasses属性
  • 该属性用于记录内部类与宿主类之间的关联。如果一个类中定义了内部类,那么编译器将会为它及它所包含的内部类生成InnerClasses属性。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,734评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,931评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,133评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,532评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,585评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,462评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,262评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,153评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,587评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,792评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,919评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,635评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,237评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,855评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,983评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,048评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,864评论 2 354

推荐阅读更多精彩内容