JAVA虚拟机学习笔记3-类文件结构

以下面的例子做讲解。
JAVA代码:
在这里插入图片描述
CLASS文件:
在这里插入图片描述

3.1 魔数与版本号

Class文件的前4个字节为魔数,十六进制:CAFEBABE (00000000:0-3)
接下来的4个字节为版本号:00 00 00 31 (0000000:4-7)代表JDK1.6.0_01 –targer1.5的版本。

3.2 常量池

常量池数量描述

前2个字节代表常量数量,如:00 16(00000000:8-9),代表有21个常量(从1开始,0是空出来的)。

常量类型

常量池的每一项常量都是一个表,常量类型如下表所示。

类型标志描述
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_MothodType_info16标志方法类型
CONSTANT_MethodHandle_info15表示方法句柄
CONSTANT_InvokeDynamic_info18表示一个动态方法调用点
每一个类型对应不同结构,但是有一个共同点就是每一个常量的第一个字节描述的就是类型。
下面描述2个类型的结构表。
CONSTANT_utf8_info
类型名称数量
u1tag1
u2Length1
u1byteslength
例子:图中01(00000000:d)代表类型CONSTANT_utf8_info,那么接下来00 11(00000000:e-f)代表长度,长度为十进制17,那么接下来(00000010:0 - 00000020:0)代表这常量的值为:com/lin/TestClass。
CONSTANT_Class_info
类型名称数量
u1tag1
u2name_index1
例子:图中07(00000000:a)代表类型CONSTANT_Class_info,接下来00 02(00000000:b-c)代表引用的是第二个常量的值。
常量池中的14中常量项的结构总表如下:
常量项目类型
CONSTANT_Utf8_infotagu1
CONSTANT_Utf8_infolengthu2
CONSTANT_Utf8_infobytesu1
CONSTANT_Integer_infotagu1
CONSTANT_Integer_infobytesu4
CONSTANT_Float_infotagu1
CONSTANT_Float_infobytesu4
CONSTANT_Long_infotagu1
CONSTANT_Long_infobytesu8
CONSTANT_Double_infotagu1
CONSTANT_Double_infobytesu8
CONSTANT_Class_infotagu1
CONSTANT_Class_infoindexu2
CONSTANT_String_infotagu1
CONSTANT_String_infoindexu2
CONSTANT_Fieldref_infotagu1
CONSTANT_Fieldref_infoindexu2
CONSTANT_Fieldref_infoindexu2
CONSTANT_Methodref_infotagu1
CONSTANT_Methodref_infoindexu2
CONSTANT_Methodref_infoindexu2
CONSTANT_InrerfaceMethodref_infotagu1
CONSTANT_InrerfaceMethodref_infoindexu2
CONSTANT_InrerfaceMethodref_infoindexu2
CONSTANT_NameAndType_infotagu1
CONSTANT_NameAndType_infoindexu2
CONSTANT_NameAndType_infoindexu2
CONSTANT_MethodHandle_infotagu1
CONSTANT_MethodHandle_inforeference_kindu1
CONSTANT_MethodHandle_inforeference_indexu2
CONSTANT_MethodType_infotagu1
CONSTANT_MethodType_infodescriptor_indexu2
CONSTANT_InvokeDynamic_infotagu1
CONSTANT_InvokeDynamic_infobootstrap_method_attr_indexu2
CONSTANT_InvokeDynamic_infoname_and_type_indexu2

Javap

我们可以利用javap命令反编译出class,常量池如下:
在这里插入图片描述

字面量

类似于java中的常量,比如String,或者修饰final的常量值。

符号引用

包括下面三种常量:

  1. 类和接口的全限定名
  2. 字段的名称和描述符
  3. 方法的名称和描述符

3.3 访问标志

常量池结束后,紧接着的2个字节代表访问标志位(access_flags),这个标志位识别这个class是类还是接口;是否定义为public类型;是否定义abstract类型;是否声明为final等。标志位的含义如下表:

标志名称标志值含义
ACC_PUBLIC0x0001是否为public类型
ACC_FINAL0x0010是否被声明为final
ACC_SUPER0x0020是否使用invokespecial字节码指令,JDK1.0.2之后为真
ACC_INTERFACE0x0200标示为一个接口
ACC_ABSTRACT0x0400是否为abstract:接口和抽象类为真
ACC_SYNTHETIC0x1000表示这个类并非用户代码产生的
ACC_ANNOTATION0x2000表示这是一个注解
ACC_ENUM0x4000表示这是一个枚举
例子:00 21(000000d0:7-8)代表此类为public类。

3.4 类索引、父类索引与接口索引集合

类索引:u2类型的数据。00 01(000000d0:9-a),引用第1个常量。即:com.lin.TestClass
父类索引:u2类型的数据。00 03(000000d0:b-c),引用第3个常量。即:java.lang.Object
接口索引:一组u2类型的数据。00 00(000000d0:d-e),为0代表没有实现接口。如果有实现接口,那么这个数代表实现多少个接口,接下来的多少个u2指向对于接口。

3.5 字段表集合

用于描述接口或者类中声明的变量。包括类级变量以及实例级变量,但不包括方法内部变量。
Class字段表集合第一个u2字节代表变量数量,之后开始描述各个变量。
例子:00 01(000000d0:f – 000000e0:0)代表变量数量为1。

变量的描述结构如下:

类型名称数量
u2access_flags 修饰位1
u2name_index 变量名称1
u2descriptor_index 变量类型1
u2attributes_count 属性表集合数量1
attribute_infoAttributes 属性表attributes_count
其中修饰位对应表如下
标志位名称标志值含义
ACC_PUBLIC0x0001Public
ACC_PRIVATE0x0002Private
ACC_PROTECTED0x0004Protected
ACC_STATIC0x0008Static
ACC_FINAL0x0010Final
ACC_VOLATILE0x0040Volatile
ACC_TRANSIENT0x0080Transient
ACC_SYNTHETIC0x1000是否有编译器自动产生
ACC_ENUM0x4000是否为enum
其中变量类型对应表如下
标识字符含义标识字符
B基本类型byteJ
C基本类型charS
D基本类型doubleZ
F基本类型floatV
I基本类型intL
例子1: 00 02(000000e0:1-2)代表修饰符,private
   00 05(000000e0:3-4)代表名称,映射到常量第5个。
   00 06(000000e0:5-6)代表变量类型,6代表映射到常量第6个。
   00 00(000000e0:7-8)代表属性表数量,这里为0。

注:属性表将在3.7中的属性表集合介绍。
#3.6 方法表集合
存储对方法的描述。第一个u2是描述方法数量。
例子:00 02(000000e0:9-a)代表存在2个方法
结构与字段表集合类似,结构如下

类型名称数量
u2access_flags 修饰位1
u2name_index 方法名称1
u2descriptor_index 方法描述符1
u2attributes_count 属性表集合数量1
attribute_infoAttributes 属性表attributes_count
其中修饰位对应表如下
标志位名称标志值含义
ACC_PUBLIC0x0001Public
ACC_PRIVATE0x0002Private
ACC_PROTECTED0x0004Protected
ACC_STATIC0x0008Static
ACC_FINAL0x0010Final
ACC_SYNCHRONIZED0x0020synchronized
ACC_BRIDGE0x0040方法是否有编译器产生的桥接方法
ACC_VARARGS0x0080方法是否接受不定参数
ACC_NATIVE0x0100native
ACC_ABSTRACT0x0400abstract
ACC_STRICTFP0x0800strictifp
ACC_ENUM0x1000native
例子1:00 01(000000e0:b-c)代表修饰符,public
  00 07(000000e0:d-e)代表方法名称,常量第7个:<init>
  00 08(000000e0:f-000000f0:0)代表方法描述符,常量第8个:()V。
  00 01(000000f0:1-2)代表方法在属性表集合存在1个属性。
  00 09(000000f0:3-4)代表属性对应第9个常量:Code

例子2:00 01(00000120:8-9)代表修饰符,public
00 10(00000120:a-b)代表方法名称,常量第16个:inc
00 11(00000120:c-d)代表方法描述符,常量第17个:()I。
00 01(00000120:c-d)代表方法在属性表集合存在1个熟悉。
00 09(00000130:0-1)代表属性对应第9个常量:Code

3.7 属性表集合

存在于字段表集合和方法表集合里面,用于描述某些场景专有的信息。

预定义属性

预定义的属性表如下21项:

属性名称使用位置含义
Code方法表Java代码编译成的字节码指令
ConstantValue字段表final关键字定义的常量池
Deprecated类,方法,字段表被声明为deprecated的方法和字段
Exceptions方法表方法抛出的异常
EnclosingMethod类文件仅当一个类为局部类或者匿名类是才能拥有这个属性,这个属性用于标识这个类所在的外围方法
InnerClass类文件内部类列表
LineNumberTableCode属性Java源码的行号与字节码指令的对应关系
LocalVariableTableCode属性方法的局部便狼描述
StackMapTableCode属性JDK1.6中新增的属性,供新的类型检查检验器检查和处理目标方法的局部变量和操作数有所需要的类是否匹配
Signature类,方法表,字段表用于支持泛型情况下的方法签名
SourceFile类文件记录源文件名称
SourceDebugExtension类文件用于存储额外的调试信息
Synthetic类,方法表,字段表标志方法或字段为编译器自动生成的
LocalVariableTypeTable使用特征签名代替描述符,是为了引入泛型语法之后能描述泛型参数化类型而添加
RuntimeVisibleAnnotations类,方法表,字段表为动态注解提供支持
RuntimeInvisibleAnnotations表,方法表,字段表用于指明哪些注解是运行时不可见的
RuntimeVisibleParameterAnnotation方法表作用与RuntimeVisibleAnnotations属性类似,只不过作用对象为方法
RuntimeInvisibleParameterAnnotation方法表作用与RuntimeInvisibleAnnotations属性类似,作用对象哪个为方法参数
AnnotationDefault方法表用于记录注解类元素的默认值
BootstrapMethods类文件用于保存invokeddynamic指令引用的引导方式限定符

Code属性表的结构

类型名称数量
u2attribute_name_index1
u4attribute_length1
u2max_stack1
u2max_locals1
u4code_length1
u1codecode_length
u2exception_table_length1
exception_infoexception_tableexception_length
u2attributes_count1
attribute_infoattributesattributes_count
例子:00 09(000000f0:3-4)代表属性对应第9个常量:Code
  00 00 00 2F(000000f0:5-8)代表属性长度为十进制47。
  00 01(000000f0:9-a)代表操作数栈为1。
  00 01(000000f0:b-c)代表局部变量存储空间,单位是slot。
  00 00 00 05(000000f0:d-00000100:0)代表字节码指令数。
  2A B7 00 0A B1(00000100:1-5)代表5个指令,请查看指令表对应。
  00 00(00000100:6-7)代表异常属性表长度,0代表不存在。
  00 02(00000100:8-9)代表存在2个附加属性。

Exceptions属性

与Code属性平级的属性。与异常表不一样,异常表在于属性里面。
与Code属性平级的属性。与异常表不一样,异常表在于属性里面。

类型名称数量
u2attribute_name_index1
u2attribute_lrngth1
u2attribute_of_exception1
u2exception_index_tsblenumber_of_exceptions

LineNumberTable属性
用于描述java源码行号与字节码行号对应关系,结构如下:

类型名称数量
u2attribute_name_index1
u4attribute_length1
u2line_number_table_length1
line_number_infoline_number_tableline_number_table_length
例子:00 0C(00000100:a-b)代表属性名称,对应常量第12个,即:LineNumberTable。
  00 00 00 06(00000100:c-f)代表属性长度,为6。
  00 01(00000110:0-1)代表1个集合的对应表。
  00 00 00 03(00000110:2-5)前面一个u2代表字节码行号,后面一个u2代表java源码行号。

LocalVariableTable属性

类型名称数量
U2Attribute_name_index1
U4Attribute_length1
U2local_variable_table_length1
Local_variable_infolocal_variable_tableLocal_variable_table_length
其中local_variable_info的结构如下
类型名称数量
u2Start_pc1
u2Length1
u2Name_index1
u2Descriptor_index1
u2index1
例子:00 0D(00000110:6-7)代表代表属性名称,对应常量第13个,即:LocalVariableTable。
  00 00 00 0C(00000110:8-b)代表属性长度为十进制12。
  00 01(00000110:c-d)代表localtable长度为1。
  00 00 00 05 00 0E 00 0F 00 00(00000110:e-00000120:7)代表local_variable_info。第一个u2(00 00)代表局部变量生命周期开始字节码偏移量;第二个u2(00 05)代表作用范围长度;第三个u2(00 0E)代表局部变量名,对应常量表。第四个u2(00 0F)代表局部变量描述符,对应常量表。第五个u2(00 00)代表局部变量的slot位置。

SourceFile属性

用于记录生成这个Class文件的源码文件名称。在方法表集合后面。结构如下

类型名称数量
U2Attribute_name_index1
U4Attribute_length1
U2Sourcefile_index1
例子:00 14(00000160:9-a)代表属性名称,对应常量表十进制20,即:SourceFile
  00 00 00 02(00000160:b-e)代表属性长度,为2。
  00 15(00000160:f-00000170:0)代表属性数据,对应常量表十进制21,即:TestClass.java

其它

其它属性就不在一一列举。
另外可以使用javap –verbose命令反编译等到结果,便于查看方法内容。
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值