java.class文件结构学习

1.
u1,u2,u3,u4 表示 1字节,2字节,3字节,4字节
class文件
类型     名称     数量
u4     magic     1
u2     minor_version     1
u2     major_version     1
u2     constant_pool_count     1
cp_info     constant_pool     constant_pool_count - 1
u2     access_flags     1    (access_flags 描述的是当前类(或者接口)的访问修饰符, 如public, private等,还有该类是类,接口还是枚举等)
u2     this_class     1    (当前类的信息,索引class_index ->CONSTANT_Class_info)
u2     super_class     1    (父类的信息,索引class_index ->CONSTANT_Class_info)
u2     interfaces_count     1    (当前类接口数量)
face_info     interfaces     interfaces_count    (每一个接口占u2块,每一块有个索引然后指向CONSTANT_Class_info)
u2     fields_count     1    (当前类定义的字段(变量)的个数,但不包括从父类继承的字段)
field_info     fields     fields_count    (下面有描述)
u2     methods_count     1    (当前类中定义的方法个数,不包括从父类继承的方法)
method_info     methods     methods_count    (对方法的描述)
u2     attribute_count     1        (属性长度)
attribute_info     attributes     attributes_count    (属性数组)
0-3字节(判断该文件是否是虚拟机可接收的Class文件,就好像PE文件开头有个MZ)
4-7字节(版本号)
接下来为常量池中数据项
CONSTANT_Utf8_info ( 程序中的字符串常量, 类型的全限定名, 方法和字段的名称, 方法和字段的描述符, 属性相关字符串)
格式:
tag
length
bytes
例如
1
5
h
e
l
l
o
CONSTANT_NameAndType(表示了一个方法或一个字段)
tag
name_index(它指向常量池中的一个CONSTANT_Utf8_info, 这个CONSTANT_Utf8_info中存储的就是方法或字段的名称)
descriptor_index(它指向常量池中的一个CONSTANT_Utf8_info, 这个CONSTANT_Utf8_info中存储的就是方法或字段的描述符)
#5 = Utf8               age  
#6 = Utf8               I  
#19 = NameAndType        #5:#6          //  age:I
则有
tag 19
name 5
descriptor_index 6

CONSTANT_Integer_info(它存储的是源文件中出现的int型数据的值)
tag(3)
bytes(值)

CONSTANT_String_info(它的作用是存储文字字符串)
tag(8)
string_index(链接到CONSTANT_Utf8_info)

CONSTANT_Class_info(存储类信息)
tag(7)
name_index(CONSTANT_Utf8_info())

CONSTANT_Fieldref_info(对一个字段(变量等)的符号引用, 这个符号引用包括两部分, 一部分是该字段所在的类, 另一部分是该字段的字段名和描述符)
tag
class_index(CONSTANT_Class_info)
name_and_type_index(CONSTANT_NameAndType_info)

CONSTANT_Methodref_info(一个类中方法的符号引用)
tag(10)
class_index(CONSTANT_Class_info)
name_and_type_index(CONSTANT_NameAndType_info)

CONSTANT_InterfaceMethodref_info(接口,都差不多)

fields
field_info结构如下:
access_flags(字段的访问标志,public,private,protected,static,final,volatile,transient等)
name_index (常量池的索引,名称,CONSTANT_Utf8_info)
descriptor_index(指向常量池的索引,描述)
attributes_count(表示这个字段有几个属性)
attributes(各个属性数组,属性一般有三种,ConstantValue, Deprecated, Synthetic)

methods
method_info结构如下:
access_flags(字段的访问标志,public,private,protected,static,final,volatile,transient等)
name_index (常量池的索引,名称,CONSTANT_Utf8_info)
descriptor_index(指向常量池的索引,描述)
attributes_count(表示这个字段有几个属性)
attributes(各个属性数组,属性一般有四种,Code, Deprecated, Exceptions 和Synthetic)


attributes
attribute结构:
attribute_name_index(2字节)(指向一个CONSTANT_Utf8_info,存放当前属性名)
attribute_length(4字节)(当前属性的长度,也就是info的长度)
info

info:
sourcefile_index:(指向一个常量池索引)
类型有:
SourceFile(描述了该类是从哪个源文件中编译来的, 注意, 描述的是源文件, 而不是类, 一个源文件中可以存在多个类。)
InnerClasses 描述的是内部类和外围类的关系
Synthetic表示这个字段, 方法或类不是有用户代码生成的(即不存在与源文件中), 而是由编译器自动添加的。(内部类啥的)
ConstantValue(静态字段才可以有ConstantValue属性)
Deprecated(源文件中出现的@deprecated注解,表示类过时等等)
Exceptions(描述的是方法声明的可能会抛出的异常)

Code(最重要的属性,存放方法的字节码指令(代码), 除此之外还存放了和操作数栈,局部变量相关的信息)
结构:
attibute_name_index
attribute_length
max_stack    (当前方法被执行引擎执行的时候, 在栈帧中需要分配的操作数栈的大小)
max_locals    (当前方法被执行引擎执行的时候, 在栈帧中需要分配的局部表量表的大小)
code_length
code    (字节指令,代码)
exception_table_length
exception_table    (异常表,对方法体中try-catch_finally的描述)
attributes_count
attributes    (其他属性)

LineNumberTable属性存在于Code属性中:
它建立了字节码偏移量到源代码行号之间的联系(这个可能就是jvm计数器相关,返回行号)
LocalVariableTable属性存在于Code属性中:
建立了方法中的局部变量与源代码中的局部变量之间的对应关系,(所谓的局部变量表)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值