字节码(二)

字节码(一)中,我们介绍了字节码的基本信息。本节内容我们将深入分析字节码文件。其中涉及到的字节码例子详细内容详见 字节码(一)1.2 字节码查看

一、字节码文件

字节码看似杂乱,其实不然,它有自己的数据组织方式;

+---------------+---------------+---------------+
|	 魔数(u4)    |	小版本(u2)   |  大版本(u2)   |
+---------------+---------------+---------------+
| 常量池大小(u2) |	         常量池数据	        |
+---------------+---------------+---------------+
|  访问标记(u2)  |	当前类(u2)  |   父类(u2)     |
+---------------+---------------+---------------+
|  接口数量(u2)  |			   接口    		    |
+---------------+-------------------------------+
|  字段数量(u2)  |	           字段             |
+---------------+-------------------------------+
|  方法数量(u2)  |	           方法     	    |
+---------------+-------------------------------+
|  属性数量(u2)  |	           属性     	    |
+---------------+-------------------------------+

u1代表1个字节;
u2代表2个字节;
u4代表4个字节;
u8代表8个字节;
u代表Unsigned,无符号

二、 常量池

常量池中存储两类常量:字面量符号引用。字面量为代码中声明为final的常量值,符号引用如类和接口的全局限定名、字段的名称和描述符、方法的名称和描述符。常量池整体上分为两部分:常量池长度以及常量池数据区。

2.1、常量池长度

  • 字节码文件第9、10字节;
  • 例: 0x0021表示有33个常量(常量池计数器是从 1 开始计数的,将第 0 项常量空出来是有特殊考虑的,索引值为 0 代表“不引用任何一个常量池项”);

2.2、常量池内容

+---------------+---------------+---------------+---------------+
| 常量类型tag(u1)|	常量值       |常量类型tag(u1)|    常量值		|
+---------------+---------------+---------------+---------------+
| 常量类型tag(u1)|	                  常量值      				|
+---------------+---------------+---------------+---------------+
								……
+---------------+---------------+---------------+---------------+
| 常量类型tag(u1)|	常量值       |常量类型tag(u1)|    常量值		|
+---------------+---------------+---------------+---------------+

2.2.1常量类型

常量类型tag描述
CONSTANT_Utf8_info1UTF-8编码字符串
CONSTANT_Integer_info3整型字面量
CONSTANT_Float_info4浮点型字面量
CONSTANT_Long_info5长整形字面量
CONSTANT_Double_info6双精度浮点型字面量
CONSTANT_Class_info7类或接口的符号引用
CONSTANT_String_info8字符串类型字面量
CONSTANT_Fieldref_info9字段的符号引用
CONSTANT_Methodref_info10类中方法的符号引用
CONSTANT_InterfaceMethodref_info11接口中方法的符号引用
CONSTANT_NameAndType_info12字段与字段类型或方法与方法类型的符号引用
CONSTANT_MethodHandle_info15表示方法句柄
CONSTANT_MethodType_info16表示方法类型
CONSTANT_InvokeDynamic_info18表示一个动态方法调用点

2.2.2 常量内容

  • 不同的常量类型,其内容结构不一样,内容长度也不一样;下面提到的idx均为常量池中的有效索引(常量池计数器是从1 开始计数)
  • 例子详细内容详见 字节码(一)1.2 字节码查看
2.2.2.1 CONSTANT_String_info
+---------------+
| 字符串idx(u2) |	
+---------------+
Eg:
#13 = String             #14            // ByteCode
2.2.2.2 CONSTANT_Class_info
+---------------+
|  类名idx(u2)  |	
+---------------+
Eg:
#16 = Class              #18            // java/io/PrintStream
2.2.2.3 CONSTANT_Fieldref_info 、CONSTANT_Methodref_info、CONSTANT_InterfaceMethodref_info
+---------------+----------------+
|  类名idx(u2)  |名字和类型idx(u2) |
+---------------+----------------+
Eg:
#7 = Fieldref           #8.#9          // java/lang/System.out:Ljava/io/PrintStream;
#1 = Methodref          #2.#3          // java/lang/Object."<init>":()V
2.2.2.4 CONSTANT_Integer_info、CONSTANT_Float_info
+---------------+
|    数字(u4)   |	
+---------------+
2.2.2.5 CONSTANT_Long_info、CONSTANT_Double_info
+---------------+---------------+
|  数字高位(u4)  |	数字低位(u4)|
+---------------+---------------+
2.2.2.6 CONSTANT_Utf8_info
+---------------+---------------+
|    长度(u2)   |	具体内容     |
+---------------+---------------+
Eg:
#14 = Utf8               ByteCode
2.2.2.7 CONSTANT_NameAndType_info
+---------------+---------------+
|  名字Idx(u2)  |   描述Idx(u2)  |
+---------------+---------------+
Eg:
#3 = NameAndType        #5:#6          // "<init>":()V

2.2.3 描述符

常量池中 #28 = Utf8 ([Ljava/lang/String;)V 是个啥?
例子详细内容详见 字节码(一)1.2 字节码查看
在这里插入图片描述

  • 1、图中 ([Ljava/lang/String;)V为方法描述符对应void main(java.lang.String[]) ;我们来拆解下:
([Ljava/lang/String;) V
 -------------------  -
  方法形参字段描述符    ^
					  |
		         返回类型描述
  • 2、图中 [Ljava/lang/String;为字段描述符,对应java.lang.String[];我们来拆解下:
[ L java/lang/String ;
- - ---------------  -
^ ^ 引用类型类名(2)   引用类型结束标识(3)
| |
| 引用类型标识符开始标识(1)
数组
  • 3、描述符速查表
标识符标识类型备注
Bbyte
Cchar
Ddouble
Ffloat
Iint
JlongL被对象类型用了,换用J
L ClassName ;reference对象类型
Sshort
ZbooleanB被byte用了,换用Z
[reference一维数组标识,二维‘[[’,以此类推
Vvoid返回void

问:Object m(int i, double d, Thread t) {...}对应的方法描述符是啥?
答:(IDLjava/lang/Thread;)Ljava/lang/Object;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值