03-字节码的结构

字节码的整体结构

字节码整体分为10个部分

所占字节 分类 备注
4个字节 Magic Number(魔数) 正确字节码标识为,由Java之父定义,固定的是CAFE BABE
2 + 2个字节 Minor Version + Major Version 编译的JDK版本号,Minor Version为小版本,Major Version为大版本。但不包括Update版本
2 + N个字节 Constant Pool(常量池) 并不是都是常量,而是指字节码中的一块数据字典,其他地方仅仅引用常量池内的地址。前2个字节是用来表示当前常量池的长度。常量池内常量个数为常量池长度 - 1,因为常量池是从下标1开始的。下标0是保留位,默认保存null。
2个字节 Access Flag 访问标识(ACC_Public、ACC_Static等)
2个字节 This Class Name 类名(全路径限定名称),是一个引用直接引用常量池内的内容
2个字节 Super Class Name 父类名,是一个引用直接引用常量池内的内容
2 + N个字节 Interfaces 当前类所实现的全部接口
2 + N个字节 Fields 当前类所拥有的所有字段
2 + N个字节 Methods 当前类所拥有的所有方法(每个方法都会有一个属性叫Code,里面是该方法的指令集。一般来说每个Code还会带有2个属性,LineNumberTable和LocalVaribleTable来分别记录字节码对应源码的行号和方法的变量表)
2 + N个字节 Attrubites 所有属性(最常见的就是Source File)

在上表中,Fields、Methods等属性均是2 + N个字节,其中固定的2个字节表示的当前分类的元素个数,如果为0则不会存在后面的N个字节,而是直接进入下一个分类的内容。

描述符

另外对于常量池中还有一部分内容需要特别强调,JVM对每种数据类型及每个方法都存在对应的描述符用来精简字节码的结构和长度,下面给出常用的描述符

8种基本类型 + void

Java类型 描述符
Byte B
Short S
Int I
Long J
Float F
Double D
Char C
Boolean Z
Void V

对象类型

L+对象的权限定名称(其中的.替换成/)+ ;

如Object的对象描述符为:Ljava/lang/Object;

String的对象描述符为:Ljava/lang/String;

数组类型

以 '[' 开头后面接数组的元素类型,如果是基本类型就是 [ + 对应的基本类型的描述符,如果是对象类型数组则是 [ + 对象描述符。示例如下:

基本类型:int[] -> [I, byte[] -> [B

对象类型:Integer[] -> [Ljava/lang/Integer; , String[]

方法的描述符

方法描述符是对方法的返回值+参数进行精简,对方法名并不产生影响。其结构是(方法参数类型描述符)+返回值类型的描述符。示例如下:

// 该方法的方法描述符为 (I)V
public void test(int a ){...} 
// 该方法的方法描述符为 (ILjava/lang/Integer;)I
public int add(int a,Integer b){...}

Fields Table的结构

每个Field都是按照如下的数据结构来存储信息的。

属性长度 属性名 备注
u2 access_flags 访问标识
u2 name_index 字段名在常量池中的索引
u2 Descriptor_index 字段描述符在常量池中的索引
u2 Attributes_count 属性个数
Attribute_info 属性信息,是一个长度为Attributes_count的数组

Methods Table的结构

方法表的数据结构与字段表一样,需要额外说明的是Attribute_info的结构,从上表可以看出Attribute_info是一个长度为Attributes_count的数组,我们现在来分析数组内的数据结构。

属性长度 属性名 备注
U2 Attrubite_name_index 属性名称在常量池中的索引
U4 Attribute_length 属性长度
U1 Info[Attribute_length] 属性信息

JVM一般会内置一些属性,但是也允许编译器自定义属性写入class文件,供运行时使用。其中最重要的一个属性是Code。下面我们会详细介绍Code属性。

Method Attribute之Code Attribute

Code属性是用来保存方法的结构(指令)。其数据结构如下所示:

Code_attribute {
  u2 attribute_name_index;  // 属性名称索引
  u4 attribute_length;          // 属性长度
  u2 max_stack;                         // 最大栈深度
  u2 max_locals;                        // 最大局部变量表个数
  u4 code_length;                       // 代码长度
  u1 code[code_length];         // 代码数组(指令数组)
  u2 exception_table_length;// 异常表长度 
  {
    u2 start_pc;   // 起始位置
    u2 end_pc;     // 结束位置
    u2 handler_pc; // 异常处理器
    u2 catch_type; // 异常类型
  } exception_table[exception_table_length];// 异常表,表示在[start_pc,end_pc)范围内如果出现catch_type类型的异常则交由handler_pc来处理,当catch_type为0是表示处理所有异常
  u2 attribute_count;           // 属性个数
  attribute_info attributes[attribute_count] // 属性信息
}

上述结构中大多数情况下attributes有2个,分别是前文提到的LineNumberTable和LocalVaribleTable。而LocalVaribleTable的长度与max_locals相等。

调用方法的指令

指令 说明
Invokeinterface 调用接口内的方法,实际上是在运行期决定的,决定到底调用那个实现的方法
Invokestatic 调用静态方法
Invokespecial 调用私有、构造方法及父类的方法
Invokevirtual 调用虚方法,即需要在运行期动态查找的方法,和invokeinterface有点类似,但不是借口中的方法,而是类似于子类、方法重写等情况。
Invokedynamic 调用动态方法

与上表中提到的虚方法对应的是非虚方法,他们是在编译器就能够决定的,在类加载阶段就能将符号引用转为直接应用。他们分别是:

  • 静态方法
  • 父类方法
  • 构造方法
  • 私有方法(无法被重写)

到此为止字节码模块相关内容就介绍到这里。由于本人能力有限,所表达的内容难免会有错误,欢迎大家评论或私信我指出,我们共同讨论进步。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,384评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,845评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,148评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,640评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,731评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,712评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,703评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,473评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,915评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,227评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,384评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,063评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,706评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,302评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,531评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,321评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,248评论 2 352

推荐阅读更多精彩内容